mirror of
https://github.com/matrix-org/mjolnir.git
synced 2024-10-01 01:36:06 -04:00
nits picked
This commit is contained in:
parent
06287ebb33
commit
6e7763ae84
@ -403,7 +403,7 @@ export class Mjolnir {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read org.matrix.mjolnir.setting state object, find any saved settings for
|
* Read org.matrix.mjolnir.setting state event, find any saved settings for
|
||||||
* the requested protectionName, then iterate and validate against their parser
|
* the requested protectionName, then iterate and validate against their parser
|
||||||
* counterparts in IProtection.settings and return those which validate
|
* counterparts in IProtection.settings and return those which validate
|
||||||
*
|
*
|
||||||
@ -411,17 +411,17 @@ export class Mjolnir {
|
|||||||
* @returns Every saved setting for this protectionName that has a valid value
|
* @returns Every saved setting for this protectionName that has a valid value
|
||||||
*/
|
*/
|
||||||
public async getProtectionSettings(protectionName: string): Promise<{ [setting: string]: any }> {
|
public async getProtectionSettings(protectionName: string): Promise<{ [setting: string]: any }> {
|
||||||
const settingDefinitions = PROTECTIONS[protectionName].factory().settings;
|
|
||||||
let savedSettings: { [setting: string]: any } = {}
|
let savedSettings: { [setting: string]: any } = {}
|
||||||
try {
|
try {
|
||||||
savedSettings = await this.client.getRoomStateEvent(
|
savedSettings = await this.client.getRoomStateEvent(
|
||||||
this.managementRoomId, 'org.matrix.mjolnir.setting', protectionName
|
this.managementRoomId, 'org.matrix.mjolnir.setting', protectionName
|
||||||
)
|
);
|
||||||
} catch {
|
} catch {
|
||||||
// setting does not exist, return empty object
|
// setting does not exist, return empty object
|
||||||
return savedSettings;
|
return savedSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const settingDefinitions = PROTECTIONS[protectionName].factory().settings;
|
||||||
const validatedSettings: { [setting: string]: any } = {}
|
const validatedSettings: { [setting: string]: any } = {}
|
||||||
for (let [key, value] of Object.entries(savedSettings)) {
|
for (let [key, value] of Object.entries(savedSettings)) {
|
||||||
if (
|
if (
|
||||||
@ -433,6 +433,12 @@ export class Mjolnir {
|
|||||||
&& settingDefinitions[key].validate(value)
|
&& settingDefinitions[key].validate(value)
|
||||||
) {
|
) {
|
||||||
validatedSettings[key] = value;
|
validatedSettings[key] = value;
|
||||||
|
} else {
|
||||||
|
await logMessage(
|
||||||
|
LogLevel.WARN,
|
||||||
|
"getProtectionSetting",
|
||||||
|
`Tried to read ${protectionName}.${key} and got invalid value ${value}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return validatedSettings;
|
return validatedSettings;
|
||||||
@ -453,13 +459,14 @@ export class Mjolnir {
|
|||||||
for (let [key, value] of Object.entries(changedSettings)) {
|
for (let [key, value] of Object.entries(changedSettings)) {
|
||||||
if (!(key in settingDefinitions)) {
|
if (!(key in settingDefinitions)) {
|
||||||
throw new ProtectionSettingValidationError(`Failed to find protection setting by name: ${key}`);
|
throw new ProtectionSettingValidationError(`Failed to find protection setting by name: ${key}`);
|
||||||
} else if (typeof(settingDefinitions[key].value) !== typeof(value)) {
|
|
||||||
throw new ProtectionSettingValidationError(`Invalid type for protection setting: ${key} (${typeof(value)})`);
|
|
||||||
} else if (!settingDefinitions[key].validate(value)) {
|
|
||||||
throw new ProtectionSettingValidationError(`Invalid value for protection setting: ${key} (${value})`);
|
|
||||||
} else {
|
|
||||||
validatedSettings[key] = value;
|
|
||||||
}
|
}
|
||||||
|
if (typeof(settingDefinitions[key].value) !== typeof(value)) {
|
||||||
|
throw new ProtectionSettingValidationError(`Invalid type for protection setting: ${key} (${typeof(value)})`);
|
||||||
|
}
|
||||||
|
if (!settingDefinitions[key].validate(value)) {
|
||||||
|
throw new ProtectionSettingValidationError(`Invalid value for protection setting: ${key} (${value})`);
|
||||||
|
}
|
||||||
|
validatedSettings[key] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.client.sendStateEvent(
|
await this.client.sendStateEvent(
|
||||||
|
@ -131,8 +131,10 @@ export async function handleCommand(roomId: string, event: any, mjolnir: Mjolnir
|
|||||||
"!mjolnir protections - List all available protections\n" +
|
"!mjolnir protections - List all available protections\n" +
|
||||||
"!mjolnir enable <protection> - Enables a particular protection\n" +
|
"!mjolnir enable <protection> - Enables a particular protection\n" +
|
||||||
"!mjolnir disable <protection> - Disables a particular protection\n" +
|
"!mjolnir disable <protection> - Disables a particular protection\n" +
|
||||||
"!mjolnir set <protection>.<setting> [value] - Change a projection setting\n" +
|
"!mjolnir config set <protection>.<setting> [value] - Change a projection setting\n" +
|
||||||
"!mjolnir get [protection] - List protection settings\n" +
|
"!mjolnir config add <protection>.<setting> [value] - Add a value to a list protection setting\n" +
|
||||||
|
"!mjolnir config remove <protection>.<setting> [value] - Remove a value from a list protection setting\n" +
|
||||||
|
"!mjolnir config get [protection] - List protection settings\n" +
|
||||||
"!mjolnir rooms - Lists all the protected rooms\n" +
|
"!mjolnir rooms - Lists all the protected rooms\n" +
|
||||||
"!mjolnir rooms add <room alias/ID> - Adds a protected room (may cause high server load)\n" +
|
"!mjolnir rooms add <room alias/ID> - Adds a protected room (may cause high server load)\n" +
|
||||||
"!mjolnir rooms remove <room alias/ID> - Removes a protected room\n" +
|
"!mjolnir rooms remove <room alias/ID> - Removes a protected room\n" +
|
||||||
|
@ -41,16 +41,28 @@ enum ConfigAction {
|
|||||||
Remove
|
Remove
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Process a given ConfigAction against a given protection setting
|
||||||
|
*
|
||||||
|
* @param mjolnir Current Mjolnir instance
|
||||||
|
* @param parts Arguments given to the command being processed
|
||||||
|
* @param action Which ConfigAction to do to the provided protection setting
|
||||||
|
* @returns Command success or failure message
|
||||||
|
*/
|
||||||
async function _execConfigChangeProtection(mjolnir: Mjolnir, parts: string[], action: ConfigAction): Promise<string> {
|
async function _execConfigChangeProtection(mjolnir: Mjolnir, parts: string[], action: ConfigAction): Promise<string> {
|
||||||
const [protectionName, ...settingParts] = parts[0].split(".");
|
const [protectionName, ...settingParts] = parts[0].split(".");
|
||||||
const protection = PROTECTIONS[protectionName];
|
const protection = PROTECTIONS[protectionName];
|
||||||
if (protection === undefined) return `Unknown protection ${protectionName}`;
|
if (protection === undefined) {
|
||||||
|
return `Unknown protection ${protectionName}`;
|
||||||
|
}
|
||||||
|
|
||||||
const defaultSettings = protection.factory().settings
|
const defaultSettings = protection.factory().settings
|
||||||
const settingName = settingParts[0];
|
const settingName = settingParts[0];
|
||||||
const stringValue = parts[1];
|
const stringValue = parts[1];
|
||||||
|
|
||||||
if (!(settingName in defaultSettings)) return `Unknown setting ${settingName}`;
|
if (!(settingName in defaultSettings)) {
|
||||||
|
return `Unknown setting ${settingName}`;
|
||||||
|
}
|
||||||
|
|
||||||
const parser = defaultSettings[settingName];
|
const parser = defaultSettings[settingName];
|
||||||
// we don't need to validate `value`, because mjolnir.setProtectionSettings does
|
// we don't need to validate `value`, because mjolnir.setProtectionSettings does
|
||||||
@ -135,18 +147,20 @@ export async function execConfigRemoveProtection(roomId: string, event: any, mjo
|
|||||||
*/
|
*/
|
||||||
export async function execConfigGetProtection(roomId: string, event: any, mjolnir: Mjolnir, parts: string[]) {
|
export async function execConfigGetProtection(roomId: string, event: any, mjolnir: Mjolnir, parts: string[]) {
|
||||||
let pickProtections = Object.keys(PROTECTIONS);
|
let pickProtections = Object.keys(PROTECTIONS);
|
||||||
// this means the output is sorted by protection name
|
|
||||||
pickProtections.sort();
|
|
||||||
|
|
||||||
if (parts.length < 3) {
|
if (parts.length < 3) {
|
||||||
// no specific protectionName provided, show all of them
|
// no specific protectionName provided, show all of them.
|
||||||
} else if (!pickProtections.includes(parts[0])) {
|
|
||||||
const errMsg = `Unknown protection: ${parts[0]}`;
|
// sort output by protection name
|
||||||
const errReply = RichReply.createFor(roomId, event, errMsg, errMsg);
|
pickProtections.sort();
|
||||||
errReply["msgtype"] = "m.notice";
|
|
||||||
await mjolnir.client.sendMessage(roomId, errReply);
|
|
||||||
return;
|
|
||||||
} else {
|
} else {
|
||||||
|
if (!pickProtections.includes(parts[0])) {
|
||||||
|
const errMsg = `Unknown protection: ${parts[0]}`;
|
||||||
|
const errReply = RichReply.createFor(roomId, event, errMsg, errMsg);
|
||||||
|
errReply["msgtype"] = "m.notice";
|
||||||
|
await mjolnir.client.sendMessage(roomId, errReply);
|
||||||
|
return;
|
||||||
|
}
|
||||||
pickProtections = [parts[0]];
|
pickProtections = [parts[0]];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,6 +189,9 @@ export async function execConfigGetProtection(roomId: string, event: any, mjolni
|
|||||||
value = savedSettings[settingName]
|
value = savedSettings[settingName]
|
||||||
|
|
||||||
text += `* ${protectionName}.${settingName}: ${value}`;
|
text += `* ${protectionName}.${settingName}: ${value}`;
|
||||||
|
// `protectionName` and `settingName` are user-provided but
|
||||||
|
// validated against the names of existing protections and their
|
||||||
|
// settings, so XSS is avoided for these already
|
||||||
html += `<li><code>${protectionName}.${settingName}</code>: <code>${htmlEscape(value)}</code></li>`
|
html += `<li><code>${protectionName}.${settingName}</code>: <code>${htmlEscape(value)}</code></li>`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,8 @@ import { LogLevel, LogService } from "matrix-bot-sdk";
|
|||||||
import { logMessage } from "../LogProxy";
|
import { logMessage } from "../LogProxy";
|
||||||
import config from "../config";
|
import config from "../config";
|
||||||
|
|
||||||
export const MAX_PER_MINUTE = 10; // if this is exceeded, we'll ban the user for spam and redact their messages
|
// if this is exceeded, we'll ban the user for spam and redact their messages
|
||||||
|
export const DEFAULT_MAX_PER_MINUTE = 10;
|
||||||
const TIMESTAMP_THRESHOLD = 30000; // 30s out of phase
|
const TIMESTAMP_THRESHOLD = 30000; // 30s out of phase
|
||||||
|
|
||||||
export class BasicFlooding implements IProtection {
|
export class BasicFlooding implements IProtection {
|
||||||
@ -29,7 +30,7 @@ export class BasicFlooding implements IProtection {
|
|||||||
private lastEvents: { [roomId: string]: { [userId: string]: { originServerTs: number, eventId: string }[] } } = {};
|
private lastEvents: { [roomId: string]: { [userId: string]: { originServerTs: number, eventId: string }[] } } = {};
|
||||||
private recentlyBanned: string[] = [];
|
private recentlyBanned: string[] = [];
|
||||||
|
|
||||||
maxPerMinute = new NumberProtectionSetting(MAX_PER_MINUTE);
|
maxPerMinute = new NumberProtectionSetting(DEFAULT_MAX_PER_MINUTE);
|
||||||
settings = {};
|
settings = {};
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2021 The Matrix.org Foundation C.I.C.
|
Copyright 2022 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@ -44,19 +44,22 @@ export interface IProtectionSetting<TChange, TValue> {
|
|||||||
}
|
}
|
||||||
export interface IProtectionListSetting<TChange, TValue> extends IProtectionSetting<TChange, TValue> {
|
export interface IProtectionListSetting<TChange, TValue> extends IProtectionSetting<TChange, TValue> {
|
||||||
/*
|
/*
|
||||||
|
* Add `data` to the current setting value, and return that new object
|
||||||
*
|
*
|
||||||
|
* @param data Value to add to the current setting value
|
||||||
|
* @returns The potential new value of this setting object
|
||||||
*/
|
*/
|
||||||
addValue(data: TChange): TValue;
|
addValue(data: TChange): TValue;
|
||||||
/*
|
/*
|
||||||
|
* Remove `data` from the current setting value, and return that new object
|
||||||
*
|
*
|
||||||
|
* @param data Value to remove from the current setting value
|
||||||
|
* @returns The potential new value of this setting object
|
||||||
*/
|
*/
|
||||||
removeValue(data: TChange): TValue;
|
removeValue(data: TChange): TValue;
|
||||||
}
|
}
|
||||||
export function isListSetting(object: any): object is IProtectionListSetting<any, any> {
|
|
||||||
return ("addValue" in object && "removeValue" in object);
|
|
||||||
}
|
|
||||||
|
|
||||||
class ProtectionSetting<TChange, TValue> implements IProtectionSetting<TChange, TValue> {
|
class AbstractProtectionSetting<TChange, TValue> implements IProtectionSetting<TChange, TValue> {
|
||||||
value: TValue
|
value: TValue
|
||||||
fromString(data: string): TChange | undefined {
|
fromString(data: string): TChange | undefined {
|
||||||
throw new Error("not Implemented");
|
throw new Error("not Implemented");
|
||||||
@ -68,7 +71,7 @@ class ProtectionSetting<TChange, TValue> implements IProtectionSetting<TChange,
|
|||||||
this.value = data;
|
this.value = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
class ProtectionListSetting<TChange, TValue> extends ProtectionSetting<TChange, TValue> implements IProtectionListSetting<TChange, TValue> {
|
class AbstractProtectionListSetting<TChange, TValue> extends AbstractProtectionSetting<TChange, TValue> implements IProtectionListSetting<TChange, TValue> {
|
||||||
addValue(data: TChange): TValue {
|
addValue(data: TChange): TValue {
|
||||||
throw new Error("not Implemented");
|
throw new Error("not Implemented");
|
||||||
}
|
}
|
||||||
@ -76,13 +79,17 @@ class ProtectionListSetting<TChange, TValue> extends ProtectionSetting<TChange,
|
|||||||
throw new Error("not Implemented");
|
throw new Error("not Implemented");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
export function isListSetting(object: any): object is IProtectionListSetting<any, any> {
|
||||||
|
return ("addValue" in object && "removeValue" in object);
|
||||||
|
}
|
||||||
|
|
||||||
export class StringProtectionSetting extends ProtectionSetting<string, string> {
|
|
||||||
|
export class StringProtectionSetting extends AbstractProtectionSetting<string, string> {
|
||||||
value = "";
|
value = "";
|
||||||
fromString = (data) => data;
|
fromString = (data) => data;
|
||||||
validate = (data) => true;
|
validate = (data) => true;
|
||||||
}
|
}
|
||||||
export class StringListProtectionSetting extends ProtectionListSetting<string, string[]> {
|
export class StringListProtectionSetting extends AbstractProtectionListSetting<string, string[]> {
|
||||||
value: string[] = [];
|
value: string[] = [];
|
||||||
fromString = (data) => data;
|
fromString = (data) => data;
|
||||||
validate = (data) => true;
|
validate = (data) => true;
|
||||||
@ -95,7 +102,7 @@ export class StringListProtectionSetting extends ProtectionListSetting<string, s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class NumberProtectionSetting extends ProtectionSetting<number, number> {
|
export class NumberProtectionSetting extends AbstractProtectionSetting<number, number> {
|
||||||
min: number|undefined;
|
min: number|undefined;
|
||||||
max: number|undefined;
|
max: number|undefined;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ limitations under the License.
|
|||||||
|
|
||||||
import { FirstMessageIsImage } from "./FirstMessageIsImage";
|
import { FirstMessageIsImage } from "./FirstMessageIsImage";
|
||||||
import { IProtection } from "./IProtection";
|
import { IProtection } from "./IProtection";
|
||||||
import { BasicFlooding, MAX_PER_MINUTE } from "./BasicFlooding";
|
import { BasicFlooding, DEFAULT_MAX_PER_MINUTE } from "./BasicFlooding";
|
||||||
import { WordList } from "./WordList";
|
import { WordList } from "./WordList";
|
||||||
import { MessageIsVoice } from "./MessageIsVoice";
|
import { MessageIsVoice } from "./MessageIsVoice";
|
||||||
import { MessageIsMedia } from "./MessageIsMedia";
|
import { MessageIsMedia } from "./MessageIsMedia";
|
||||||
@ -28,7 +28,7 @@ export const PROTECTIONS: PossibleProtections = {
|
|||||||
factory: () => new FirstMessageIsImage(),
|
factory: () => new FirstMessageIsImage(),
|
||||||
},
|
},
|
||||||
[new BasicFlooding().name]: {
|
[new BasicFlooding().name]: {
|
||||||
description: "If a user posts more than " + MAX_PER_MINUTE + " messages in 60s they'll be " +
|
description: "If a user posts more than " + DEFAULT_MAX_PER_MINUTE + " messages in 60s they'll be " +
|
||||||
"banned for spam. This does not publish the ban to any of your ban lists.",
|
"banned for spam. This does not publish the ban to any of your ban lists.",
|
||||||
factory: () => new BasicFlooding(),
|
factory: () => new BasicFlooding(),
|
||||||
},
|
},
|
||||||
|
@ -26,28 +26,28 @@ describe("Test: Protection settings", function() {
|
|||||||
it("Mjolnir successfully saves valid protection setting values", async function() {
|
it("Mjolnir successfully saves valid protection setting values", async function() {
|
||||||
this.timeout(20000);
|
this.timeout(20000);
|
||||||
|
|
||||||
PROTECTIONS["test"] = {
|
PROTECTIONS["05OVMS"] = {
|
||||||
description: "A test protection",
|
description: "A test protection",
|
||||||
factory: () => new class implements IProtection {
|
factory: () => new class implements IProtection {
|
||||||
name = "test";
|
name = "05OVMS";
|
||||||
async handleEvent(mjolnir: Mjolnir, roomId: string, event: any) {};
|
async handleEvent(mjolnir: Mjolnir, roomId: string, event: any) {};
|
||||||
settings = { test: new NumberProtectionSetting(3) };
|
settings = { test: new NumberProtectionSetting(3) };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
await this.mjolnir.setProtectionSettings("test", { test: 123 });
|
await this.mjolnir.setProtectionSettings("05OVMS", { test: 123 });
|
||||||
assert.equal(
|
assert.equal(
|
||||||
(await this.mjolnir.getProtectionSettings("test"))["test"],
|
(await this.mjolnir.getProtectionSettings("05OVMS"))["test"],
|
||||||
123
|
123
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
it("Mjolnir should accumulate changed settings", async function() {
|
it("Mjolnir should accumulate changed settings", async function() {
|
||||||
this.timeout(20000);
|
this.timeout(20000);
|
||||||
|
|
||||||
PROTECTIONS["test"] = {
|
PROTECTIONS["HPUjKN"] = {
|
||||||
description: "A test protection",
|
description: "A test protection",
|
||||||
factory: () => new class implements IProtection {
|
factory: () => new class implements IProtection {
|
||||||
name = "test";
|
name = "HPUjKN";
|
||||||
async handleEvent(mjolnir: Mjolnir, roomId: string, event: any) {};
|
async handleEvent(mjolnir: Mjolnir, roomId: string, event: any) {};
|
||||||
settings = {
|
settings = {
|
||||||
test1: new NumberProtectionSetting(3),
|
test1: new NumberProtectionSetting(3),
|
||||||
@ -56,20 +56,20 @@ describe("Test: Protection settings", function() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
await this.mjolnir.setProtectionSettings("test", { test1: 1 });
|
await this.mjolnir.setProtectionSettings("HPUjKN", { test1: 1 });
|
||||||
await this.mjolnir.setProtectionSettings("test", { test2: 2 });
|
await this.mjolnir.setProtectionSettings("HPUjKN", { test2: 2 });
|
||||||
const settings = await this.mjolnir.getProtectionSettings("test");
|
const settings = await this.mjolnir.getProtectionSettings("HPUjKN");
|
||||||
//assert.equal(settings["test1"], 1);
|
assert.equal(settings["test1"], 1);
|
||||||
assert.equal(settings["test2"], 2);
|
assert.equal(settings["test2"], 2);
|
||||||
});
|
});
|
||||||
it("Mjolnir responds to !set correctly", async function() {
|
it("Mjolnir responds to !set correctly", async function() {
|
||||||
this.timeout(20000);
|
this.timeout(20000);
|
||||||
await client.joinRoom(config.managementRoom);
|
await client.joinRoom(config.managementRoom);
|
||||||
|
|
||||||
PROTECTIONS["test"] = {
|
PROTECTIONS["JY2TPN"] = {
|
||||||
description: "A test protection",
|
description: "A test protection",
|
||||||
factory: () => new class implements IProtection {
|
factory: () => new class implements IProtection {
|
||||||
name = "test";
|
name = "JY2TPN";
|
||||||
async handleEvent(mjolnir: Mjolnir, roomId: string, event: any) {};
|
async handleEvent(mjolnir: Mjolnir, roomId: string, event: any) {};
|
||||||
settings = { test: new StringProtectionSetting() };
|
settings = { test: new StringProtectionSetting() };
|
||||||
}
|
}
|
||||||
@ -78,26 +78,26 @@ describe("Test: Protection settings", function() {
|
|||||||
|
|
||||||
let reply = new Promise((resolve, reject) => {
|
let reply = new Promise((resolve, reject) => {
|
||||||
client.on('room.message', noticeListener(this.mjolnir.managementRoomId, (event) => {
|
client.on('room.message', noticeListener(this.mjolnir.managementRoomId, (event) => {
|
||||||
if (event.content.body.includes("Changed test.test ")) {
|
if (event.content.body.includes("Changed JY2TPN.test ")) {
|
||||||
resolve(event);
|
resolve(event);
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
});
|
});
|
||||||
|
|
||||||
await client.sendMessage(this.mjolnir.managementRoomId, {msgtype: "m.text", body: "!mjolnir config set test.test asd"})
|
await client.sendMessage(this.mjolnir.managementRoomId, {msgtype: "m.text", body: "!mjolnir config set JY2TPN.test asd"})
|
||||||
await reply
|
await reply
|
||||||
|
|
||||||
const settings = await this.mjolnir.getProtectionSettings("test");
|
const settings = await this.mjolnir.getProtectionSettings("JY2TPN");
|
||||||
assert.equal(settings["test"], "asd");
|
assert.equal(settings["test"], "asd");
|
||||||
});
|
});
|
||||||
it("Mjolnir adds a value to a list setting", async function() {
|
it("Mjolnir adds a value to a list setting", async function() {
|
||||||
this.timeout(20000);
|
this.timeout(20000);
|
||||||
await client.joinRoom(config.managementRoom);
|
await client.joinRoom(config.managementRoom);
|
||||||
|
|
||||||
PROTECTIONS["test"] = {
|
PROTECTIONS["r33XyT"] = {
|
||||||
description: "A test protection",
|
description: "A test protection",
|
||||||
factory: () => new class implements IProtection {
|
factory: () => new class implements IProtection {
|
||||||
name = "test";
|
name = "r33XyT";
|
||||||
async handleEvent(mjolnir: Mjolnir, roomId: string, event: any) {};
|
async handleEvent(mjolnir: Mjolnir, roomId: string, event: any) {};
|
||||||
settings = { test: new StringListProtectionSetting() };
|
settings = { test: new StringListProtectionSetting() };
|
||||||
}
|
}
|
||||||
@ -106,25 +106,25 @@ describe("Test: Protection settings", function() {
|
|||||||
|
|
||||||
let reply = new Promise((resolve, reject) => {
|
let reply = new Promise((resolve, reject) => {
|
||||||
client.on('room.message', noticeListener(this.mjolnir.managementRoomId, (event) => {
|
client.on('room.message', noticeListener(this.mjolnir.managementRoomId, (event) => {
|
||||||
if (event.content.body.includes("Changed test.test ")) {
|
if (event.content.body.includes("Changed r33XyT.test ")) {
|
||||||
resolve(event);
|
resolve(event);
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
});
|
});
|
||||||
|
|
||||||
await client.sendMessage(this.mjolnir.managementRoomId, {msgtype: "m.text", body: "!mjolnir config add test.test asd"})
|
await client.sendMessage(this.mjolnir.managementRoomId, {msgtype: "m.text", body: "!mjolnir config add r33XyT.test asd"})
|
||||||
await reply
|
await reply
|
||||||
|
|
||||||
assert.deepEqual(await this.mjolnir.getProtectionSettings("test"), { "test": ["asd"] });
|
assert.deepEqual(await this.mjolnir.getProtectionSettings("r33XyT"), { "test": ["asd"] });
|
||||||
});
|
});
|
||||||
it("Mjolnir removes a value from a list setting", async function() {
|
it("Mjolnir removes a value from a list setting", async function() {
|
||||||
this.timeout(20000);
|
this.timeout(20000);
|
||||||
await client.joinRoom(config.managementRoom);
|
await client.joinRoom(config.managementRoom);
|
||||||
|
|
||||||
PROTECTIONS["test"] = {
|
PROTECTIONS["oXzT0E"] = {
|
||||||
description: "A test protection",
|
description: "A test protection",
|
||||||
factory: () => new class implements IProtection {
|
factory: () => new class implements IProtection {
|
||||||
name = "test";
|
name = "oXzT0E";
|
||||||
async handleEvent(mjolnir: Mjolnir, roomId: string, event: any) {};
|
async handleEvent(mjolnir: Mjolnir, roomId: string, event: any) {};
|
||||||
settings = { test: new StringListProtectionSetting() };
|
settings = { test: new StringListProtectionSetting() };
|
||||||
}
|
}
|
||||||
@ -134,7 +134,7 @@ describe("Test: Protection settings", function() {
|
|||||||
let reply = new Promise((resolve, reject) => {
|
let reply = new Promise((resolve, reject) => {
|
||||||
let i = 0;
|
let i = 0;
|
||||||
client.on('room.message', noticeListener(this.mjolnir.managementRoomId, (event) => {
|
client.on('room.message', noticeListener(this.mjolnir.managementRoomId, (event) => {
|
||||||
if (event.content.body.includes("Changed test.test ")) {
|
if (event.content.body.includes("Changed oXzT0E.test ")) {
|
||||||
if (++i == 2) {
|
if (++i == 2) {
|
||||||
resolve(event);
|
resolve(event);
|
||||||
}
|
}
|
||||||
@ -142,11 +142,11 @@ describe("Test: Protection settings", function() {
|
|||||||
}))
|
}))
|
||||||
});
|
});
|
||||||
|
|
||||||
await client.sendMessage(this.mjolnir.managementRoomId, {msgtype: "m.text", body: "!mjolnir config add test.test asd"})
|
await client.sendMessage(this.mjolnir.managementRoomId, {msgtype: "m.text", body: "!mjolnir config add oXzT0E.test asd"})
|
||||||
await client.sendMessage(this.mjolnir.managementRoomId, {msgtype: "m.text", body: "!mjolnir config remove test.test asd"})
|
await client.sendMessage(this.mjolnir.managementRoomId, {msgtype: "m.text", body: "!mjolnir config remove oXzT0E.test asd"})
|
||||||
await reply
|
await reply
|
||||||
|
|
||||||
assert.deepEqual(await this.mjolnir.getProtectionSettings("test"), { "test": [] });
|
assert.deepEqual(await this.mjolnir.getProtectionSettings("oXzT0E"), { "test": [] });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user