From 601aa33bc640cf93281207489bd29188ab15807a Mon Sep 17 00:00:00 2001 From: gnuxie Date: Thu, 31 Aug 2023 15:40:24 +0100 Subject: [PATCH 01/23] Remove Mjolnir's ErrorCache. A bizarre contraption. The ErrorCache was seemingly introduced to reduce the number of errors in the management room. https://github.com/matrix-org/mjolnir/commit/82214c6cd88d83abed05fec4a871a874e6e0265b It makes sense why it was added if you consider that many admins will run Draupnir without giving it the permission to manage server ACL in its rooms. Though, I'm not sure why then you would add the error cache rather than properly supporting that use case. So perhaps there were other reasons. Either way, what is drawing the line for me is that the ErrorCache will suppress any error within rooms that is not a permission error, if there was any error that was not a permission error within a 15 minute window. Considering the typical Draupnir will not even sync for hours at a time, even in large communities. It does present a problem for rooms with a lot of join/leave events. I think that's probably why the error cache was added. Ahh, well, fuck. Well what is the real solution to this? The real solution when the kind is acl is to allow the bot to run without applying ACLs. Ok fine but, hey wait a minute. Why would there be any other kind of persistent error when banning someone that would be unimportant enough to silently hide in an ErrorCache?? IDK let's just add an opttion to disable server ACL, since they might want to use another tool for that anyhow. Out of scope for the current work though. https://github.com/Gnuxie/Draupnir/pull/85 --- src/ErrorCache.ts | 89 ---------------------------- src/ProtectedRoomsSet.ts | 8 +-- src/models/RoomUpdateError.ts | 3 + src/protections/ProtectionManager.ts | 2 +- src/queues/EventRedactionQueue.ts | 2 +- 5 files changed, 6 insertions(+), 98 deletions(-) delete mode 100644 src/ErrorCache.ts diff --git a/src/ErrorCache.ts b/src/ErrorCache.ts deleted file mode 100644 index 4bb154ae..00000000 --- a/src/ErrorCache.ts +++ /dev/null @@ -1,89 +0,0 @@ -/** - * Copyright (C) 2022 Gnuxie - * All rights reserved. - * - * This file is modified and is NOT licensed under the Apache License. - * This modified file incorperates work from mjolnir - * https://github.com/matrix-org/mjolnir - * which included the following license notice: - -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. - * - * However, this file is modified and the modifications in this file - * are NOT distributed, contributed, committed, or licensed under the Apache License. - */ - -export const ERROR_KIND_PERMISSION = "permission"; -export const ERROR_KIND_FATAL = "fatal"; - -const TRIGGER_INTERVALS: { [key: string]: number } = { - [ERROR_KIND_PERMISSION]: 3 * 60 * 60 * 1000, // 3 hours - [ERROR_KIND_FATAL]: 15 * 60 * 1000, // 15 minutes -}; - -/** - * The ErrorCache is used to suppress the same error messages for the same error state. - * An example would be when mjolnir has been told to protect a room but is missing some permission such as the ability to send `m.room.server_acl`. - * Each time `Mjolnir` synchronizes policies to protected rooms Mjolnir will try to log to the management room that Mjolnir doesn't have permission to send `m.room.server_acl`. - * The ErrorCache is an attempt to make sure the error is reported only once. - */ -export default class ErrorCache { - private roomsToErrors: Map> = new Map(); - - constructor() { - } - - /** - * Reset the error cache for a room/kind in the situation where circumstances have changed e.g. if Mjolnir has been informed via sync of a `m.room.power_levels` event in the room, we would want to clear `ERROR_KIND_PERMISSION` - * so that a user can see if their changes worked. - * @param roomId The room to reset the error cache for. - * @param kind The kind of error we are resetting. - */ - public resetError(roomId: string, kind: string) { - if (!this.roomsToErrors.has(roomId)) { - this.roomsToErrors.set(roomId, new Map()); - } - this.roomsToErrors.get(roomId)?.set(kind, 0); - } - - /** - * Register the error with the cache. - * @param roomId The room where the error is occuring or related to. - * @param kind What kind of error, either `ERROR_KIND_PERMISSION` or `ERROR_KIND_FATAL`. - * @returns True if the error kind has been triggered in that room, - * meaning it has been longer than the time specified in `TRIGGER_INTERVALS` since the last trigger (or the first trigger). Otherwise false. - */ - public triggerError(roomId: string, kind: string): boolean { - if (!this.roomsToErrors.get(roomId)) { - this.roomsToErrors.set(roomId, new Map()); - } - - const triggers = this.roomsToErrors.get(roomId)!; - if (!triggers.has(kind)) { - triggers?.set(kind, 0); - } - - const lastTriggerTime = triggers.get(kind)!; - const now = new Date().getTime(); - const interval = TRIGGER_INTERVALS[kind]; - - if ((now - lastTriggerTime) >= interval) { - triggers.set(kind, now); - return true; - } else { - return false; - } - } -} diff --git a/src/ProtectedRoomsSet.ts b/src/ProtectedRoomsSet.ts index 9833b876..ce42d55a 100644 --- a/src/ProtectedRoomsSet.ts +++ b/src/ProtectedRoomsSet.ts @@ -28,13 +28,12 @@ limitations under the License. import { LogLevel, LogService, MatrixGlob, UserID } from "matrix-bot-sdk"; import { Permalinks } from "./commands/interface-manager/Permalinks"; import { IConfig } from "./config"; -import ErrorCache, { ERROR_KIND_FATAL, ERROR_KIND_PERMISSION } from "./ErrorCache"; import ManagementRoomOutput from "./ManagementRoomOutput"; import { MatrixSendClient } from "./MatrixEmitter"; import AccessControlUnit, { Access } from "./models/AccessControlUnit"; import { RULE_ROOM, RULE_SERVER, RULE_USER } from "./models/ListRule"; import PolicyList, { ListRuleChange, Revision } from "./models/PolicyList"; -import { RoomUpdateError } from "./models/RoomUpdateError"; +import { ERROR_KIND_FATAL, ERROR_KIND_PERMISSION, RoomUpdateError } from "./models/RoomUpdateError"; import { ProtectionManager } from "./protections/ProtectionManager"; import { EventRedactionQueue, RedactUserInRoom } from "./queues/EventRedactionQueue"; import { ProtectedRoomActivityTracker } from "./queues/ProtectedRoomActivityTracker"; @@ -75,8 +74,6 @@ export class ProtectedRoomsSet { */ private readonly eventRedactionQueue = new EventRedactionQueue(); - private readonly errorCache = new ErrorCache(); - /** * These are globs sourced from `config.automaticallyRedactForReasons` that are matched against the reason of an * `m.ban` recommendation against a user. @@ -205,8 +202,6 @@ export class ProtectedRoomsSet { } this.protectedRoomActivityTracker.handleEvent(roomId, event); if (event['type'] === 'm.room.power_levels' && event['state_key'] === '') { - // power levels were updated - recheck permissions - this.errorCache.resetError(roomId, ERROR_KIND_PERMISSION); await this.managementRoomOutput.logMessage(LogLevel.DEBUG, "Mjolnir", `Power levels changed in ${roomId} - checking permissions...`, roomId); const errors = await this.protectionManager.verifyPermissionsIn(roomId); const hadErrors = await this.printActionResult(errors); @@ -481,7 +476,6 @@ export class ProtectedRoomsSet { if (errors.length <= 0) return false; if (!logAnyways) { - errors = errors.filter(e => this.errorCache.triggerError(e.roomId, e.errorKind)); if (errors.length <= 0) { LogService.warn("Mjolnir", "Multiple errors are happening, however they are muted. Please check the management room."); return true; diff --git a/src/models/RoomUpdateError.ts b/src/models/RoomUpdateError.ts index f3ab3588..169dedc8 100644 --- a/src/models/RoomUpdateError.ts +++ b/src/models/RoomUpdateError.ts @@ -25,6 +25,9 @@ limitations under the License. * are NOT distributed, contributed, committed, or licensed under the Apache License. */ +export const ERROR_KIND_PERMISSION = "permission"; +export const ERROR_KIND_FATAL = "fatal"; + export interface RoomUpdateError { roomId: string; errorMessage: string; diff --git a/src/protections/ProtectionManager.ts b/src/protections/ProtectionManager.ts index 7a44c0ee..4e408503 100644 --- a/src/protections/ProtectionManager.ts +++ b/src/protections/ProtectionManager.ts @@ -39,7 +39,7 @@ import { LogLevel, LogService } from "matrix-bot-sdk"; import { ProtectionSettingValidationError } from "./ProtectionSettings"; import { Consequence } from "./consequence"; import { htmlEscape } from "../utils"; -import { ERROR_KIND_FATAL, ERROR_KIND_PERMISSION } from "../ErrorCache"; +import { ERROR_KIND_FATAL, ERROR_KIND_PERMISSION } from "../models/RoomUpdateError"; import { RoomUpdateError } from "../models/RoomUpdateError"; import { BanPropagation } from "./BanPropagation"; import { MatrixDataManager, RawSchemedData, SchemaMigration, SCHEMA_VERSION_KEY } from "../models/MatrixDataManager"; diff --git a/src/queues/EventRedactionQueue.ts b/src/queues/EventRedactionQueue.ts index 9d7d88a6..2a6d6f3b 100644 --- a/src/queues/EventRedactionQueue.ts +++ b/src/queues/EventRedactionQueue.ts @@ -25,7 +25,7 @@ limitations under the License. * are NOT distributed, contributed, committed, or licensed under the Apache License. */ import { LogLevel, MatrixClient } from "matrix-bot-sdk" -import { ERROR_KIND_FATAL } from "../ErrorCache"; +import { ERROR_KIND_FATAL } from "../models/RoomUpdateError"; import { RoomUpdateError } from "../models/RoomUpdateError"; import { redactUserMessagesIn } from "../utils"; import ManagementRoomOutput from "../ManagementRoomOutput"; From ea49b0a5363861b3729dcc720ff091b2480c4165 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Thu, 31 Aug 2023 23:07:29 +0100 Subject: [PATCH 02/23] Use JSX for the protected rooms set's `printActionResult`. We've done this to make the implementation a lot cleaner and managable. However, we've taken the opportunity to simplify all of the client code that would use this method. Some of these simplifications might come at a small cost. Updating server ACL, member bans and checking power levels would all be clearly titled as seperate checks. However, it should still be obvious what has gone wrong, since any error would have to give a more detailed explanation. And not everything is going to fail all at once (and if it does, there are bigger issues). a lot cleaner https://github.com/Gnuxie/Draupnir/pull/85 --- src/ProtectedRoomsSet.ts | 103 +++++------------- src/commands/PermissionCheckCommand.ts | 2 +- .../interface-manager/DeadDocumentMatrix.ts | 1 + src/models/RoomUpdateError.ts | 35 ------ src/models/RoomUpdateError.tsx | 103 ++++++++++++++++++ 5 files changed, 130 insertions(+), 114 deletions(-) delete mode 100644 src/models/RoomUpdateError.ts create mode 100644 src/models/RoomUpdateError.tsx diff --git a/src/ProtectedRoomsSet.ts b/src/ProtectedRoomsSet.ts index ce42d55a..121cdabd 100644 --- a/src/ProtectedRoomsSet.ts +++ b/src/ProtectedRoomsSet.ts @@ -25,15 +25,14 @@ limitations under the License. * are NOT distributed, contributed, committed, or licensed under the Apache License. */ -import { LogLevel, LogService, MatrixGlob, UserID } from "matrix-bot-sdk"; -import { Permalinks } from "./commands/interface-manager/Permalinks"; +import { LogLevel, MatrixGlob, UserID } from "matrix-bot-sdk"; import { IConfig } from "./config"; import ManagementRoomOutput from "./ManagementRoomOutput"; import { MatrixSendClient } from "./MatrixEmitter"; import AccessControlUnit, { Access } from "./models/AccessControlUnit"; import { RULE_ROOM, RULE_SERVER, RULE_USER } from "./models/ListRule"; import PolicyList, { ListRuleChange, Revision } from "./models/PolicyList"; -import { ERROR_KIND_FATAL, ERROR_KIND_PERMISSION, RoomUpdateError } from "./models/RoomUpdateError"; +import { ERROR_KIND_FATAL, ERROR_KIND_PERMISSION, printActionResult, RoomUpdateError } from "./models/RoomUpdateError"; import { ProtectionManager } from "./protections/ProtectionManager"; import { EventRedactionQueue, RedactUserInRoom } from "./queues/EventRedactionQueue"; import { ProtectedRoomActivityTracker } from "./queues/ProtectedRoomActivityTracker"; @@ -204,20 +203,20 @@ export class ProtectedRoomsSet { if (event['type'] === 'm.room.power_levels' && event['state_key'] === '') { await this.managementRoomOutput.logMessage(LogLevel.DEBUG, "Mjolnir", `Power levels changed in ${roomId} - checking permissions...`, roomId); const errors = await this.protectionManager.verifyPermissionsIn(roomId); - const hadErrors = await this.printActionResult(errors); - if (!hadErrors) { - await this.managementRoomOutput.logMessage(LogLevel.DEBUG, "Mjolnir", `All permissions look OK.`); - } + await this.printActionResult(errors, { title: "There were errors verifying permissions.", noErrorsText: "All permissions look OK."}); return; } else if (event['type'] === "m.room.member") { // The reason we have to apply bans on each member change is because // we cannot eagerly ban users (that is to ban them when they have never been a member) // as they can be force joined to a room they might not have known existed. // Only apply bans and then redactions in the room we are currently looking at. - const banErrors = await this.applyUserBans([roomId]); - const redactionErrors = await this.processRedactionQueue(roomId); - await this.printActionResult(banErrors); - await this.printActionResult(redactionErrors); + const errors = [ + await this.applyUserBans([roomId]), + await this.processRedactionQueue(roomId), + ].flat(); + if (errors.length > 0) { + await this.printActionResult(errors, { title: 'There were errors updating member bans.' }); + } } } @@ -225,26 +224,12 @@ export class ProtectedRoomsSet { * Synchronize all the protected rooms with all of the policies described in the watched policy lists. */ private async syncRoomsWithPolicies() { - let hadErrors = false; - const [aclErrors, banErrors] = await Promise.all([ + const errors = (await Promise.all([ this.applyServerAcls(this.policyLists, this.protectedRoomsByActivity()), - this.applyUserBans(this.protectedRoomsByActivity()) - ]); - const redactionErrors = await this.processRedactionQueue(); - hadErrors = hadErrors || await this.printActionResult(aclErrors, "Errors updating server ACLs:"); - hadErrors = hadErrors || await this.printActionResult(banErrors, "Errors updating member bans:"); - hadErrors = hadErrors || await this.printActionResult(redactionErrors, "Error updating redactions:"); - - if (!hadErrors) { - const html = `Done updating rooms - no errors`; - const text = "Done updating rooms - no errors"; - await this.client.sendMessage(this.managementRoomId, { - msgtype: "m.notice", - body: text, - format: "org.matrix.custom.html", - formatted_body: html, - }); - } + this.applyUserBans(this.protectedRoomsByActivity()), + this.processRedactionQueue() + ])).flat(); + await this.printActionResult(errors, { title: "There were errors synchronising the protected rooms." }); } /** @@ -472,63 +457,25 @@ export class ProtectedRoomsSet { return true; } - private async printActionResult(errors: RoomUpdateError[], title: string | null = null, logAnyways = false) { - if (errors.length <= 0) return false; - - if (!logAnyways) { - if (errors.length <= 0) { - LogService.warn("Mjolnir", "Multiple errors are happening, however they are muted. Please check the management room."); - return true; - } - } - - let html = ""; - let text = ""; - - const htmlTitle = title ? `${title}
` : ''; - const textTitle = title ? `${title}\n` : ''; - - html += `${htmlTitle}${errors.length} errors updating protected rooms!
    `; - text += `${textTitle}${errors.length} errors updating protected rooms!\n`; - const viaServers = [(new UserID(await this.client.getUserId())).domain]; - for (const error of errors) { - const alias = (await this.client.getPublishedAlias(error.roomId)) || error.roomId; - const url = Permalinks.forRoom(alias, viaServers); - html += `
  • ${alias} - ${error.errorMessage}
  • `; - text += `${url} - ${error.errorMessage}\n`; - } - html += "
"; - - const message = { - msgtype: "m.notice", - body: text, - format: "org.matrix.custom.html", - formatted_body: html, - }; - await this.client.sendMessage(this.managementRoomId, message); - return true; + private async printActionResult( + errors: RoomUpdateError[], + renderOptions: { title?: string, noErrorsText?: string } + ): Promise { + printActionResult(this.client, this.managementRoomId, errors, renderOptions); } public requiredProtectionPermissions() { throw new TypeError("Unimplemented, need to put protections into here too.") } - public async verifyPermissions(verbose = true, printRegardless = false) { + public async verifyPermissions() { const errors: RoomUpdateError[] = []; for (const roomId of this.protectedRooms) { errors.push(...(await this.protectionManager.verifyPermissionsIn(roomId))); } - - const hadErrors = await this.printActionResult(errors, "Permission errors in protected rooms:", printRegardless); - if (!hadErrors && verbose) { - const html = `All permissions look OK.`; - const text = "All permissions look OK."; - await this.client.sendMessage(this.managementRoomId, { - msgtype: "m.notice", - body: text, - format: "org.matrix.custom.html", - formatted_body: html, - }); - } + await this.printActionResult(errors, { + title: "There are permission errors in protected rooms.", + noErrorsText: "All permissions look OK." + }); } } diff --git a/src/commands/PermissionCheckCommand.ts b/src/commands/PermissionCheckCommand.ts index ad384a7a..765c2d85 100644 --- a/src/commands/PermissionCheckCommand.ts +++ b/src/commands/PermissionCheckCommand.ts @@ -29,5 +29,5 @@ import { Mjolnir } from "../Mjolnir"; // !mjolnir verify export async function execPermissionCheckCommand(roomId: string, event: any, mjolnir: Mjolnir) { - return mjolnir.protectedRoomsTracker.verifyPermissions(true, true); + return mjolnir.protectedRoomsTracker.verifyPermissions(); } diff --git a/src/commands/interface-manager/DeadDocumentMatrix.ts b/src/commands/interface-manager/DeadDocumentMatrix.ts index b9980232..81f1489f 100644 --- a/src/commands/interface-manager/DeadDocumentMatrix.ts +++ b/src/commands/interface-manager/DeadDocumentMatrix.ts @@ -31,6 +31,7 @@ export async function renderMatrix(node: DocumentNode, cb: SendMatrixEventCB): P context.output.commit(commitNode); }; if (node.tag !== NodeTag.Root) { + // rendering has to start (and end) with a committable node. throw new TypeError("Tried to render a node without a root, this will not be committable"); } const markdownOutput = new PagedDuplexStream(); diff --git a/src/models/RoomUpdateError.ts b/src/models/RoomUpdateError.ts deleted file mode 100644 index 169dedc8..00000000 --- a/src/models/RoomUpdateError.ts +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright (C) 2022 Gnuxie - * All rights reserved. - * - * This file is modified and is NOT licensed under the Apache License. - * This modified file incorperates work from mjolnir - * https://github.com/matrix-org/mjolnir - * which included the following license notice: - -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. - * - * However, this file is modified and the modifications in this file - * are NOT distributed, contributed, committed, or licensed under the Apache License. - */ - -export const ERROR_KIND_PERMISSION = "permission"; -export const ERROR_KIND_FATAL = "fatal"; - -export interface RoomUpdateError { - roomId: string; - errorMessage: string; - errorKind: string; -} diff --git a/src/models/RoomUpdateError.tsx b/src/models/RoomUpdateError.tsx new file mode 100644 index 00000000..03ca4b8f --- /dev/null +++ b/src/models/RoomUpdateError.tsx @@ -0,0 +1,103 @@ +/** + * Copyright (C) 2022 Gnuxie + * All rights reserved. + * + * This file is modified and is NOT licensed under the Apache License. + * This modified file incorperates work from mjolnir + * https://github.com/matrix-org/mjolnir + * which included the following license notice: + +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. + * + * However, this file is modified and the modifications in this file + * are NOT distributed, contributed, committed, or licensed under the Apache License. + */ + +import { UserID } from "matrix-bot-sdk"; +import { DocumentNode } from "../commands/interface-manager/DeadDocument"; +import { renderMatrixAndSend } from "../commands/interface-manager/DeadDocumentMatrix"; +import { JSXFactory } from "../commands/interface-manager/JSXFactory"; +import { Permalinks } from "../commands/interface-manager/Permalinks"; +import { MatrixSendClient } from "../MatrixEmitter"; + +export const ERROR_KIND_PERMISSION = "permission"; +export const ERROR_KIND_FATAL = "fatal"; + +export interface RoomUpdateError { + roomId: string; + errorMessage: string; + errorKind: string; +} + +function renderErrorItem(error: RoomUpdateError, viaServers: string[]): DocumentNode { + return
  • + {error.roomId} - {error.errorMessage} +
  • +} + +/** + * Render a message to show to the user after taking an action in a room or a set of rooms. + * @param client A matrix client. + * @param errors Any errors associated with the action. + * @param options.title To give context about what the action was, shown when there are errors. + * @param options.noErrorsText To show when there are no errors. + * @param options.skipNoErrors is ineffective and does nothing, it is an option for the accompnying `printActionResult`. + * @returns A `DocumentNode` fragment that can be sent to Matrix or incorperated into another message. + */ +export async function renderActionResult( + client: MatrixSendClient, + errors: RoomUpdateError[], + { title = 'There were errors updating protected rooms.', noErrorsText = 'Done updating rooms - no errors.'}: { title?: string, noErrorsText?: string } = {} +): Promise { + if (errors.length === 0) { + return {noErrorsText} + } + // This is a little unfortunate because for some reason we don't have a way to keep + // room references around that have vias and are meaningful + // there isn't really any easy way to do this :( + const viaServers = [(new UserID(await client.getUserId())).domain]; + return + + {title}
    + {errors.length} errors updating protected rooms!
    +
    +
      + {errors.map(error => renderErrorItem(error, viaServers))} +
    +
    +} + +/** + * Render a message to represent the outcome of an action in an update. + * @param client A matrix client to send a notice with. + * @param roomId The room to send the notice to. + * @param errors Any errors that are a result of the action. + * @param options.title To give context about what the action was, shown when there are errors. + * @param options.noErrorsText To show when there are no errors. + * @returns + */ +export async function printActionResult( + client: MatrixSendClient, + roomId: string, + errors: RoomUpdateError[], + renderOptions: { title?: string, noErrorsText?: string } = {} +): Promise { + await renderMatrixAndSend( + {await renderActionResult(client, errors, renderOptions)}, + roomId, + undefined, + client, + ) +} From 1e82c15d82fbb9b15c4eef68fd96c472b665a3f4 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Fri, 1 Sep 2023 19:21:58 +0100 Subject: [PATCH 03/23] Add font tag to DeadDocument https://github.com/Gnuxie/Draupnir/pull/85 --- .../interface-manager/DeadDocument.ts | 1 + .../interface-manager/DeadDocumentHtml.ts | 32 +++++++++++++------ .../interface-manager/DeadDocumentMarkdown.ts | 3 ++ 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/commands/interface-manager/DeadDocument.ts b/src/commands/interface-manager/DeadDocument.ts index 0c4bf00e..08a27f57 100644 --- a/src/commands/interface-manager/DeadDocument.ts +++ b/src/commands/interface-manager/DeadDocument.ts @@ -66,6 +66,7 @@ export enum NodeTag { Fragment = 'fragment', Details = 'details', Summary = 'summary', + Font = 'font', } /** diff --git a/src/commands/interface-manager/DeadDocumentHtml.ts b/src/commands/interface-manager/DeadDocumentHtml.ts index 5166b4aa..1b2e202a 100644 --- a/src/commands/interface-manager/DeadDocumentHtml.ts +++ b/src/commands/interface-manager/DeadDocumentHtml.ts @@ -4,9 +4,26 @@ */ import { htmlEscape } from "../../utils"; -import { FringeLeafRenderFunction, FringeType, LeafNode, NodeTag, SimpleFringeRenderer } from "./DeadDocument"; +import { DocumentNode, FringeLeafRenderFunction, FringeType, LeafNode, NodeTag, SimpleFringeRenderer, TagDynamicEnvironment } from "./DeadDocument"; import { blank, staticString, TransactionalOutputContext } from "./DeadDocumentMarkdown"; +function writeAttributableNode(tagName: string, _fringe: FringeType, node: DocumentNode, context: TransactionalOutputContext, _environment: TagDynamicEnvironment) { + context.output.writeString(`<${tagName}`); + if (node.attributeMap.size > 0) { + for (const [key, value] of node.attributeMap.entries()) { + context.output.writeString(` ${htmlEscape(key)}="${htmlEscape(value)}"`); + } + } + context.output.writeString('>') +} + +function attributableNode(tagName: string) { + return function(fringe: FringeType, node: DocumentNode, context: TransactionalOutputContext, environment: TagDynamicEnvironment) { + writeAttributableNode(tagName, fringe, node, context, environment); + } +} + + export const HTML_RENDERER = new SimpleFringeRenderer(); HTML_RENDERER.registerRenderer>( @@ -52,16 +69,11 @@ HTML_RENDERER.registerRenderer'), staticString('') ).registerInnerNode(NodeTag.Anchor, - function(_fringe, node, context, _environment) { - context.output.writeString(' 0) { - for (const [key, value] of node.attributeMap.entries()) { - context.output.writeString(` ${htmlEscape(key)}="${htmlEscape(value)}"`); - } - } - context.output.writeString('>') - }, + attributableNode('a'), staticString('') +).registerInnerNode(NodeTag.Font, + attributableNode('font'), + staticString('') ).registerInnerNode(NodeTag.Root, blank, blank diff --git a/src/commands/interface-manager/DeadDocumentMarkdown.ts b/src/commands/interface-manager/DeadDocumentMarkdown.ts index 0694c0dd..19651dba 100644 --- a/src/commands/interface-manager/DeadDocumentMarkdown.ts +++ b/src/commands/interface-manager/DeadDocumentMarkdown.ts @@ -142,4 +142,7 @@ MARKDOWN_RENDERER.registerRenderer'), staticString('') +).registerInnerNode(NodeTag.Font, + blank, + blank ); From e8847a2524c3e6e7d96d916d0a5db424d2ba0057 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Fri, 1 Sep 2023 20:34:09 +0100 Subject: [PATCH 04/23] Allow Draupnir to ignore m.room.server_acl https://github.com/Gnuxie/Draupnir/pull/85 --- config/default.yaml | 4 ++++ src/ProtectedRoomsSet.ts | 3 +++ src/config.ts | 2 ++ src/protections/ProtectionManager.ts | 2 +- 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/config/default.yaml b/config/default.yaml index 42257323..d3783abc 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -73,6 +73,10 @@ verifyPermissionsOnStartup: true # turn on to trial some untrusted configuration or lists. noop: false +# Whether or not Draupnir should apply `m.room.server_acl` events. +# DO NOT change this to `true` unless you are very confident that you know what you are doing. +disableServerACL: false + # Whether Draupnir should check member lists quicker (by using a different endpoint), # keep in mind that enabling this will miss invited (but not joined) users. # diff --git a/src/ProtectedRoomsSet.ts b/src/ProtectedRoomsSet.ts index 121cdabd..07b8d6fe 100644 --- a/src/ProtectedRoomsSet.ts +++ b/src/ProtectedRoomsSet.ts @@ -293,6 +293,9 @@ export class ProtectedRoomsSet { private async applyServerAcls(lists: PolicyList[], roomIds: string[]): Promise { // we need to provide mutual exclusion so that we do not have requests updating the m.room.server_acl event // finish out of order and therefore leave the room out of sync with the policy lists. + if (this.config.disableServerACL) { + return []; + } return new Promise((resolve, reject) => { this.aclChain = this.aclChain .then(() => this._applyServerAcls(lists, roomIds)) diff --git a/src/config.ts b/src/config.ts index 01be3e3d..31e27b6d 100644 --- a/src/config.ts +++ b/src/config.ts @@ -63,6 +63,7 @@ export interface IConfig { logMutedModules: string[], syncOnStartup: boolean; verifyPermissionsOnStartup: boolean; + disableServerACL: boolean; noop: boolean; protectedRooms: string[]; // matrix.to urls fasterMembershipChecks: boolean; @@ -158,6 +159,7 @@ const defaultConfig: IConfig = { syncOnStartup: true, verifyPermissionsOnStartup: true, noop: false, + disableServerACL: false, protectedRooms: [], fasterMembershipChecks: false, automaticallyRedactForReasons: ["spam", "advertising"], diff --git a/src/protections/ProtectionManager.ts b/src/protections/ProtectionManager.ts index 4e408503..c422f8a1 100644 --- a/src/protections/ProtectionManager.ts +++ b/src/protections/ProtectionManager.ts @@ -436,7 +436,7 @@ export class ProtectionManager { errorKind: ERROR_KIND_PERMISSION, }); } - if (userLevel < aclLevel) { + if (!this.mjolnir.config.disableServerACL && userLevel < aclLevel) { errors.push({ roomId, errorMessage: `Missing power level for server ACLs: ${userLevel} < ${aclLevel}`, From 2a4829dc1e25dd18acb5ee64024aecf1339a2173 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Mon, 4 Sep 2023 15:06:07 +0100 Subject: [PATCH 05/23] Use `
    ` for error detail. https://matrix.to/#/!IaWNErZAgQUhGqJXjX:matrix.org/$634tyYnNJK_zpNb4wH1zHbYeMOsDBHMpwdWPg1GdAEU?via=matrix.org&via=the-apothecary.club&via=envs.net --- src/models/RoomUpdateError.tsx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/models/RoomUpdateError.tsx b/src/models/RoomUpdateError.tsx index 03ca4b8f..01388eb5 100644 --- a/src/models/RoomUpdateError.tsx +++ b/src/models/RoomUpdateError.tsx @@ -71,11 +71,17 @@ export async function renderActionResult( return {title}
    - {errors.length} errors updating protected rooms!
    -
      - {errors.map(error => renderErrorItem(error, viaServers))} -
    +
    + + + {errors.length} errors updating protected rooms!
    +
    +
    +
      + {errors.map(error => renderErrorItem(error, viaServers))} +
    +
    } From 29a8bec08639587f0a563798ec9dace45867fdd8 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Mon, 4 Sep 2023 20:33:58 +0100 Subject: [PATCH 06/23] Bring various documentation up to date with current events. --- CONTRIBUTING.md | 69 ++++++++++++++++++++++++++++++++++++++++++++----- README.md | 60 ++++++++++++++++++++++++++++++------------ docs/context.md | 34 +++++++++++++++++++++--- 3 files changed, 138 insertions(+), 25 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b461f17d..f49c1e20 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,13 +4,15 @@ Draupnir is licensed under the Cooperative Software License. The reason for the license is simply because this project was something that I was previously employed to work on. -I have not decided whether I will accept contributions under the same license -or another license or a CLA yet. -I will welcome advice, but I will not welcome attempts to parsuade me to re-adopt -and relicense under Apache-2.0 unless being offered compensation. +I have not decided whether I will accept contributions under the +same license or another license or a CLA yet. +I will welcome advice, but I will not welcome attempts to parsuade +me to re-adopt and relicense under Apache-2.0 unless being offered +compensation. -The easiest way forwards would be for me to accept individual contributions under -Apache-2.0. +As of now, I am accepting contributions under the Apache-2.0 license +in the same way as Mjolnir. This allows me the option to relicense +Draupnir under Apache-2.0 without needing to chase up all contributors. ## How to contribute @@ -185,3 +187,58 @@ matrix together all the fragmented communication technologies out there we are reliant on contributions and collaboration from the community to do so. So please get involved - and we hope you have as much fun hacking on Matrix as we do! + +## Further notes on license and its relation to business in general + +Ultimately most open source software contributions start by gifting +labour without any obligation or transaction. + +There is no ethical way to directly sell this labour. + +Many so called post open source[^post-open-source] ideas fixate on +finding a way to conduct business in an ethical way, +and this is problematic. + +Once you start working within capitalism with capitalism, and exchange +your power and influence over a work to monitize the work itself, +the work will gain inertia and a power of its own that you cannot control. +You will work for the work, for external interests, and these won't +be the interests of your powerless users who you were among to begin with. + +It would be extreme, but I am tempted to suggest that by performing a +buisness this way, you are part of an effort +which not only reinforces capitalism but works to make it more +efficient. Effectively working to make capitalism more powerful. +Congratulations. + +Another point that is often brought up in these discussions is how +software licensing relies on an appeal to state power, the power of +the law. + +Therefore I propose a new licensing model, one which appeals +to the power of public pressure rather than the law. + +Such a license would be liberal, allowing incorperation into +proprietary works provided it retained a notice. +However, any work which is used in any way to conduct business must +report all software being used by the buisness with this license, +all turnover made by the buisness, all profit made by the buisness +and an estimation of both profit and turnover made by the buisness in +relation to the collection of software reported. + +It is not clear to me how often these figures should be reported +and when, or even where they should be reported to (ideally they could +be found centrally). It is also unclear how to create the legalise +required. + +With the information these licenses would provide, public pressure +could then be used to demand reperations for the profits made by +pillaging and destructive businesses. +It is not clear yet how any reperations would be distributed, +probably through some system of +[venture communes](https://wiki.p2pfoundation.net/Venture_Commune). +The idea is to ensure that the developers and users of projects +would not be distracted from providing each other mutual +support and to give them a hope of escaping. + +[^post-open-source] https://applied-langua.ge/posts/the-poverty-of-post-open-source.html. diff --git a/README.md b/README.md index edc48a45..e8cb5b6b 100644 --- a/README.md +++ b/README.md @@ -5,34 +5,57 @@ for more information. > I offer you the ring, which was burned, laid upon the pyre of Baldr by Odin. -This is a hard fork of [Mjolnir](https://github.com/matrix-org/mjolnir), +This is a continuation and fork of [Mjolnir](https://github.com/matrix-org/mjolnir), with an entirely new framework for interacting with Matrix written to overcome some of the burdens there were holding development of mjolnir. ## Status -The command handler is currently being refactored and the syntax will become -incompatible with legacy Mjolnir commands. The UX will be overhauled -as such and we will consider the launch of Draupnir a 2.0.0 release. +The command handler is currently being refactored and some command syntax will become +incompatible with legacy Mjolnir commands. +The UX is being overhauled and Draupnir is slowly moving towards a 2.0.0 release. -As Draupnir heads towards `v2.0.0` releases will appear [here](https://github.com/Gnuxie/Draupnir/releases). -Until `v2.0.0` there will be frequent changes to commands. +As Draupnir heads towards `v2.0.0`, releases will appear [here](https://github.com/Gnuxie/Draupnir/releases). +Until `v2.0.0` there will be frequent changes to commands but all of these +will be noted in the changes for that release. -Migrating from Mjolnir is straightforward, and Draupnir remains backwards compatible. -So it is possible to try Draupnir and still have the option to switch back to Mjolnir. +Migrating from Mjolnir is straightforward and requires no manual steps, +migration for your setup is likely as simple as changing your server config to +pull the latest Draupnir docker image instead of a mjolnir one. +Draupnir remains backwards compatible so that it is possible to try Draupnir +and still have the option to switch back to Mjolnir. + +Any problems with migration should be reported to our [support room](https://matrix.to/#/#draupnir:matrix.org). ## Features -As an all-in-one moderation tool, it can protect your server from malicious invites, spam -messages, and whatever else you don't want. In addition to server-level protection, Draupnir -is great for communities wanting to protect their rooms without having to use their personal -accounts for moderation. +As an all-in-one moderation tool, Draupnir can protect your community by +applying policies from both your own and community curated policy lists. The bot by default includes support for bans, redactions, anti-spam, server ACLs, room -directory changes, room alias transfers, account deactivation, room shutdown, and more. +directory changes and room alias transfers. -A Synapse module is also available to apply the same rulesets the bot uses across an entire -homeserver. +Support is also provided for some Synapse admin functions such as account +deactivation and room shutdown. + +A Synapse module is also available to apply the same rulesets the bot is watching +across an entire homeserver. + +### Differences from Mjolnir + +The main difference from Mjolnir is that it is no longer necessary to use +commands for some functions. Banning a user in a protected room from your +Matrix client will cause Draupnir to show a prompt in the management room, +which will offer to add the ban to a policy list. + +If you do still wish to use the ban command, please note that users +and other entities that are being banned are now the first argument +to the ban command. It is now also possible to provide only the entity to +Draupnir and have Draupnir prompt you for the policy list and the ban reason. + +In general, any command that has been migrated to the new interface will +feature better error messages for common problems and allow admins +to trace the cause of unexpected errors much more easily. ## Setting up @@ -88,7 +111,12 @@ server can only receive requests from your reverse proxy (e.g. `localhost`). ## Development -TODO. It's a TypeScript project with a linter. +Draupnir is a TypeScript project that depends on the labour of a handful of +developers, testers and users. The code base is in relatively good shape, +and if you would like to contribute or gain an understanding of the workings +of Draupnir, please read our [context document](./docs/context.md). + +Once you have done that, go ahead and read our [contributing document](./CONTRIBUTING.md) ### Development and testing with mx-tester diff --git a/docs/context.md b/docs/context.md index 3535e7be..fcaee47e 100644 --- a/docs/context.md +++ b/docs/context.md @@ -1,9 +1,9 @@ ## Context for developing Draupnir -#### And also context that is essential if you are developing anything -that uses Policy Lists. +alternatively context that is essential for developing +anything that uses Policy Lists. -### Sync loop +### The synchronisation loop In order to understand how Draupnir works you have to first understand the sync loop of Matrix Clients. All Matrix clients have a sync loop. @@ -122,6 +122,34 @@ begin synchronising policies with with the protected rooms. Draupnir starts synchronising rooms by visiting the most recently active room first. +### A history of moderation projects + +Mjolnir was originally created by +[Travis Ralston](https://github.com/turt2live) as a good enough +solution temprarily made permanent. +The abstract architecture of Mjolnir remains today and we are +thankful for good foundations, and significantly +[policies](https://spec.matrix.org/latest/client-server-api/#moderation-policy-lists) +that were +[proposed](https://github.com/matrix-org/matrix-spec-proposals/pull/2313) +by [Matthew Hodgson](https://github.com/ara4n). + +There were several other similar solutions known to us that were +developed and deployed at the same time as Mjolnir in the earlier days +and either directly or indirectly had influence on things to come. +Notably [Fly Swatter](https://github.com/serra-allgood/matrix-fly-swatter) +and [Luna](https://gitlab.com/Gnuxie/luna). + +After a period of maintenance, Mjolnir was then developed by other +contributors from Element who restructured the project, tackled +usability concerns and would go on to produce a multi-tenancy +appservice mode of deployment called "Mjolnir for all". +With the eventual aim of integrating the functions of Mjolnir +transparently with both homeservers and clients. + +This effort is now continued by the Matrix community in the form +of Draupnir and [MTRNord](https://github.com/MTRNord)'s +[Draupnir4all deployment](https://docs.draupnir.midnightthoughts.space/). [^full-state]: matrix-bot-sdk could be modified to sync with `full_state` set to true. This has been From 73601687a8e6f88dbc5cdd7b499386f73b30747f Mon Sep 17 00:00:00 2001 From: gnuxie Date: Wed, 30 Aug 2023 13:12:36 +0100 Subject: [PATCH 07/23] Add UnbanPropagation BanPropagationProtection. https://github.com/Gnuxie/Draupnir/pull/93/ --- src/ProtectedRoomsSet.ts | 23 ++- src/commands/Rules.tsx | 2 +- src/protections/BanPropagation.tsx | 185 ++++++++++++++++++++----- test/integration/banPropagationTest.ts | 21 +++ 4 files changed, 193 insertions(+), 38 deletions(-) diff --git a/src/ProtectedRoomsSet.ts b/src/ProtectedRoomsSet.ts index 07b8d6fe..6d2cfad0 100644 --- a/src/ProtectedRoomsSet.ts +++ b/src/ProtectedRoomsSet.ts @@ -25,7 +25,7 @@ limitations under the License. * are NOT distributed, contributed, committed, or licensed under the Apache License. */ -import { LogLevel, MatrixGlob, UserID } from "matrix-bot-sdk"; +import { LogLevel, LogService, MatrixGlob, UserID } from "matrix-bot-sdk"; import { IConfig } from "./config"; import ManagementRoomOutput from "./ManagementRoomOutput"; import { MatrixSendClient } from "./MatrixEmitter"; @@ -467,6 +467,27 @@ export class ProtectedRoomsSet { printActionResult(this.client, this.managementRoomId, errors, renderOptions); } + public async unbanUser(user: string): Promise { + const errors: RoomUpdateError[] = []; + for (const room of this.protectedRoomActivityTracker.protectedRoomsByActivity()) { + try { + await this.client.unbanUser(user, room); + } catch (e) { + // FIXME: We need to know if `info` is acceptable or not. + // Technically these kinds of errors are expected to occur, + // so not sure if it warrants reporting as ERROR. + LogService.info('ProtectedRoomSet', `Unable to unban a user ${user} from ${room}`, e); + const message = e.message || (e.body ? e.body.error : ''); + errors.push({ + roomId: room, + errorMessage: message, + errorKind: message && message.includes("You don't have permission to ban") ? ERROR_KIND_PERMISSION : ERROR_KIND_FATAL, + }); + } + } + return errors; + } + public requiredProtectionPermissions() { throw new TypeError("Unimplemented, need to put protections into here too.") } diff --git a/src/commands/Rules.tsx b/src/commands/Rules.tsx index c5e605a8..5116d7fe 100644 --- a/src/commands/Rules.tsx +++ b/src/commands/Rules.tsx @@ -60,7 +60,7 @@ async function renderListMatches( ) } -function renderListRules(list: ListMatches) { +export function renderListRules(list: ListMatches) { const renderRuleSummary = (rule: ListRule, entityDescription: string) => { return
  • {entityDescription} ({rule.recommendation}): {rule.entity} ({rule.reason}) diff --git a/src/protections/BanPropagation.tsx b/src/protections/BanPropagation.tsx index 4f7e1d00..46fb4d05 100644 --- a/src/protections/BanPropagation.tsx +++ b/src/protections/BanPropagation.tsx @@ -23,6 +23,9 @@ limitations under the License. * * However, this file is modified and the modifications in this file * are NOT distributed, contributed, committed, or licensed under the Apache License. + * + * In addition to the above, I want to add that this protection was inspired by + * a Mjolnir PR that was originally created by Gergő Fándly https://github.com/matrix-org/mjolnir/pull/223 */ import { Protection } from "./Protection"; @@ -31,17 +34,19 @@ import { LogService } from "matrix-bot-sdk"; import { JSXFactory } from "../commands/interface-manager/JSXFactory"; import { renderMatrixAndSend } from "../commands/interface-manager/DeadDocumentMatrix"; import { renderMentionPill } from "../commands/interface-manager/MatrixHelpRenderer"; -import { RULE_USER } from "../models/ListRule"; +import { RULE_USER, ListRule } from "../models/ListRule"; import { UserID } from "matrix-bot-sdk"; -import { ReactionListener } from "../commands/interface-manager/MatrixReactionHandler"; -import { PolicyListManager } from "../models/PolicyListManager"; import { MatrixRoomReference } from "../commands/interface-manager/MatrixRoomReference"; import { findPolicyListFromRoomReference } from "../commands/Ban"; +import PolicyList from "../models/PolicyList"; +import { renderListRules } from "../commands/Rules"; +import { ERROR_KIND_FATAL, ERROR_KIND_PERMISSION, printActionResult, RoomUpdateError } from "../models/RoomUpdateError"; -const PROPAGATION_PROMPT_LISTENER = 'ge.applied-langua.ge.draupnir.ban_propagation'; +const BAN_PROPAGATION_PROMPT_LISTENER = 'ge.applied-langua.ge.draupnir.ban_propagation'; +const UNBAN_PROPAGATION_PROMPT_LISTENER = 'ge.applied-langua.ge.draupnir.unban_propagation'; -function makePolicyListShortcodeReferenceMap(lists: PolicyListManager): Map { - return lists.lists.reduce((map, list, index) => (map.set(`${index + 1}.`, list.roomRef), map), new Map()) +function makePolicyListShortcodeReferenceMap(lists: PolicyList[]): Map { + return lists.reduce((map, list, index) => (map.set(`${index + 1}.`, list.roomRef), map), new Map()) } // would be nice to be able to use presentation types here idk. @@ -62,7 +67,7 @@ async function promptBanPropagation( event: any, roomId: string ): Promise { - const reactionMap = makePolicyListShortcodeReferenceMap(mjolnir.policyListManager); + const reactionMap = makePolicyListShortcodeReferenceMap(mjolnir.policyListManager.lists); const promptEventId = (await renderMatrixAndSend( The user {renderMentionPill(event["state_key"], event["content"]?.["displayname"] ?? event["state_key"])} was banned in {roomId} by {new UserID(event["sender"])} for {event["content"]?.["reason"] ?? ''}.
    @@ -75,7 +80,7 @@ async function promptBanPropagation( undefined, mjolnir.client, mjolnir.reactionHandler.createAnnotation( - PROPAGATION_PROMPT_LISTENER, + BAN_PROPAGATION_PROMPT_LISTENER, reactionMap, { target: event["state_key"], @@ -87,6 +92,118 @@ async function promptBanPropagation( return promptEventId; } +async function promptUnbanPropagation( + mjolnir: Mjolnir, + event: any, + roomId: string, + rulesMatchingUser: Map +): Promise { + const reactionMap = new Map(Object.entries({ 'unban from all': 'unban from all'})); + // shouldn't we warn them that the unban will be futile? + const promptEventId = (await renderMatrixAndSend( + + The user {renderMentionPill(event["state_key"], event["content"]?.["displayname"] ?? event["state_key"])} was unbanned + from the room {roomId} by {new UserID(event["sender"])} for {event["content"]?.["reason"] ?? ''}.
    + However there are rules in Draupnir's watched lists matching this user: +
      + { + [...rulesMatchingUser.entries()] + .map(([list, rules]) =>
    • {renderListRules({ + shortcode: list.listShortcode, + roomRef: list.roomRef, + roomId: list.roomId, + matches: rules + })}
    • ) + } +
    + Would you like to remove these rules and unban the user from all protected rooms? +
    , + mjolnir.managementRoomId, + undefined, + mjolnir.client, + mjolnir.reactionHandler.createAnnotation( + UNBAN_PROPAGATION_PROMPT_LISTENER, + reactionMap, + { + target: event["state_key"], + reason: event["content"]?.["reason"], + } + ) + )).at(0) as string; + await mjolnir.reactionHandler.addReactionsToEvent(mjolnir.client, mjolnir.managementRoomId, promptEventId, reactionMap); + return promptEventId; +} + +interface ListenerContext { + mjolnir: Mjolnir, +} + +async function banReactionListener(this: ListenerContext, key: string, item: unknown, context: BanPropagationMessageContext) { + try { + if (typeof item === 'string') { + const listRef = MatrixRoomReference.fromPermalink(item); + const listResult = await findPolicyListFromRoomReference(this.mjolnir, listRef); + if (listResult.isOk()) { + return await listResult.ok.banEntity(RULE_USER, context.target, context.reason); + } else { + LogService.warn("BanPropagation", "Timed out waiting for a response to a room level ban", listResult.err); + return; + } + } else { + throw new TypeError("The ban prompt event's reaction map is malformed.") + } + } catch (e) { + LogService.error('BanPropagation', "Encountered an error while prompting the user for instructions to propagate a room level ban", e); + } +} + +async function unbanFromAllLists(mjolnir: Mjolnir, user: string): Promise { + const errors: RoomUpdateError[] = []; + for (const list of mjolnir.policyListManager.lists) { + try { + await list.unbanEntity(RULE_USER, user); + } catch (e) { + LogService.info('BanPropagation', `Could not unban ${user} from ${list.roomRef}`, e); + const message = e.message || (e.body ? e.body.error : ''); + errors.push({ + roomId: list.roomId, + errorMessage: message, + errorKind: message.includes("You don't have permission") ? ERROR_KIND_PERMISSION : ERROR_KIND_FATAL + }) + } + } + return errors; +} + +async function unbanUserReactionListener(this: ListenerContext, _key: string, item: unknown, context: BanPropagationMessageContext): Promise { + try { + if (item === 'unban from all') { + const listErrors = await unbanFromAllLists(this.mjolnir, context.target); + if (listErrors.length > 0) { + await printActionResult( + this.mjolnir.client, + this.mjolnir.managementRoomId, + listErrors, + { title: `There were errors unbanning ${context.target} from all lists.`} + ); + } else { + const unbanErrors = await this.mjolnir.protectedRoomsTracker.unbanUser(context.target); + await printActionResult( + this.mjolnir.client, + this.mjolnir.managementRoomId, + unbanErrors, + { + title: `There were errors unbanning ${context.target} from protected rooms.`, + noErrorsText: `Done unbanning ${context.target} from protected rooms - no errors.` + } + ); + } + } + } catch (e) { + LogService.error(`BanPropagationProtection`, "Unexpected error unbanning a user", e); + } +} + export class BanPropagation extends Protection { settings = {}; @@ -101,39 +218,35 @@ export class BanPropagation extends Protection { } public async registerProtection(mjolnir: Mjolnir): Promise { - const listener: ReactionListener = async (key, item, context: BanPropagationMessageContext) => { - try { - if (typeof item === 'string') { - const listRef = MatrixRoomReference.fromPermalink(item); - const listResult = await findPolicyListFromRoomReference(mjolnir, listRef); - if (listResult.isOk()) { - return listResult.ok.banEntity(RULE_USER, context.target, context.reason); - } else { - LogService.warn("BanPropagation", "Timed out waiting for a response to a room level ban", listResult.err); - return; - } - } else { - throw new TypeError("The ban prompt event's reaction map is malformed.") - } - } catch (e) { - LogService.error('BanPropagation', "Encountered an error while prompting the user for instructions to propagate a room level ban", e); - } - }; - mjolnir.reactionHandler.on(PROPAGATION_PROMPT_LISTENER, listener); + mjolnir.reactionHandler.on(BAN_PROPAGATION_PROMPT_LISTENER, banReactionListener.bind({ mjolnir })); + mjolnir.reactionHandler.on(UNBAN_PROPAGATION_PROMPT_LISTENER, unbanUserReactionListener.bind({ mjolnir })); } public async handleEvent(mjolnir: Mjolnir, roomId: string, event: any): Promise { - if (event['type'] !== 'm.room.member' || event['content']?.['membership'] !== 'ban') { + if (event['type'] !== 'm.room.member' + || !(event['content']?.['membership'] === 'ban' || event['content']?.['membership'] === 'leave')) { return; } - if (mjolnir.policyListManager.lists.map( - list => list.rulesMatchingEntity(event['state_key'], RULE_USER) - ).some(rules => rules.length > 0) - ) { - return; // The user is already banned. + const rulesMatchingUser = mjolnir.policyListManager.lists.reduce( + (listMap, list) => { + const rules = list.rulesMatchingEntity(event['state_key'], RULE_USER); + if (rules.length > 0) { + listMap.set(list, rules) + }; + return listMap + }, new Map() + ); + const userMembership = event['content']?.['membership']; + if (userMembership === 'ban') { + if (rulesMatchingUser.size > 0) { + return; // The user is already banned. + } + // do not await, we don't want to block the protection manager + promptBanPropagation(mjolnir, event, roomId) + } else if (userMembership === 'leave' && rulesMatchingUser.size > 0) { + // Then this is a banned user being unbanned. + // do not await, we don't want to block the protection manager + promptUnbanPropagation(mjolnir, event, roomId, rulesMatchingUser); } - // do not await, we don't want to block the protection manager - promptBanPropagation(mjolnir, event, roomId) - } } diff --git a/test/integration/banPropagationTest.ts b/test/integration/banPropagationTest.ts index 9b5e24d5..86b5e4c3 100644 --- a/test/integration/banPropagationTest.ts +++ b/test/integration/banPropagationTest.ts @@ -54,5 +54,26 @@ describe("Ban propagation test", function() { expect(rules.length).toBe(1); expect(rules[0].entity).toBe('@test:example.com'); expect(rules[0].reason).toBe('spam'); + + // now unban them >:3 + const unbanPrompt = await getFirstEventMatching({ + matrix: mjolnir.matrixEmitter, + targetRoom: mjolnir.managementRoomId, + lookAfterEvent: async function () { + // ban a user in one of our protected rooms using the moderator + await moderator.unbanUser('@test:example.com', protectedRooms[0]); + return undefined; + }, + predicate: function (event: any): boolean { + return (event['content']?.['body'] ?? '').startsWith('The user') + } + }); + + await moderator.unstableApis.addReactionToEvent( + mjolnir.managementRoomId, unbanPrompt['event_id'], 'unban from all' + ); + await new Promise(resolve => setTimeout(resolve, 10000)); + const rulesAfterUnban = policyList.rulesMatchingEntity('@test:example.com', RULE_USER); + expect(rulesAfterUnban.length).toBe(0); }) }) From 3ec37e3fe8233982e40e643e64a31318e381cbcf Mon Sep 17 00:00:00 2001 From: gnuxie Date: Tue, 5 Sep 2023 18:00:59 +0100 Subject: [PATCH 08/23] Introduce concept of Known and Unknown exceptions. Sometimes we don't need exceptions to be reported on the error level. This is especially true when the user does something out of order and there's a permission error. If we're aware of that possibility as developers and have accounted for it, then it's unnecessary for it to be treated the same way as a fatal error. We also decided to log CommandExceptions and CommandErrors as early as possible. https://github.com/Gnuxie/Draupnir/pull/93/ --- src/commands/CommandHandler.ts | 4 +-- src/commands/Rooms.tsx | 9 ++++-- .../interface-manager/CommandException.ts | 30 +++++++++++++++++-- src/commands/interface-manager/Validation.ts | 7 ++++- 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/commands/CommandHandler.ts b/src/commands/CommandHandler.ts index df39c90c..f2212db3 100644 --- a/src/commands/CommandHandler.ts +++ b/src/commands/CommandHandler.ts @@ -48,7 +48,7 @@ import { BaseFunction, CommandTable, defineCommandTable, findCommandTable, findT import { findMatrixInterfaceAdaptor, MatrixContext } from "./interface-manager/MatrixInterfaceAdaptor"; import { ArgumentStream } from "./interface-manager/ParameterParsing"; import { CommandResult } from "./interface-manager/Validation"; -import { CommandException } from "./interface-manager/CommandException"; +import { CommandException, CommandExceptionKind } from "./interface-manager/CommandException"; import { tickCrossRenderer } from "./interface-manager/MatrixHelpRenderer"; import "./interface-manager/MatrixPresentations"; @@ -133,7 +133,7 @@ export async function handleCommand(roomId: string, event: { content: { body: st try { return await adaptor.invoke(mjolnirContext, mjolnirContext, ...stream.rest()); } catch (e) { - const commandError = new CommandException(e, 'Unknown Unexpected Error'); + const commandError = new CommandException(CommandExceptionKind.Unknown, e, 'Unknown Unexpected Error'); await tickCrossRenderer.call(mjolnirContext, mjolnir.client, roomId, event, CommandResult.Err(commandError)); } } diff --git a/src/commands/Rooms.tsx b/src/commands/Rooms.tsx index d5cd70a2..eaf80613 100644 --- a/src/commands/Rooms.tsx +++ b/src/commands/Rooms.tsx @@ -30,7 +30,7 @@ import { findPresentationType, parameters } from "./interface-manager/ParameterP import { MjolnirContext } from "./CommandHandler"; import { MatrixRoomID, MatrixRoomReference } from "./interface-manager/MatrixRoomReference"; import { CommandResult } from "./interface-manager/Validation"; -import { CommandException } from "./interface-manager/CommandException"; +import { CommandException, CommandExceptionKind } from "./interface-manager/CommandException"; import { defineMatrixInterfaceAdaptor } from "./interface-manager/MatrixInterfaceAdaptor"; import { tickCrossRenderer } from "./interface-manager/MatrixHelpRenderer"; import { DocumentNode } from "./interface-manager/DeadDocument"; @@ -92,7 +92,7 @@ defineInterfaceCommand({ return CommandException.Result( `The homeserver that Draupnir is hosted on cannot join this room using the room reference provided.\ Try an alias or the "share room" button in your client to obtain a valid reference to the room.`, - { exception: e } + { exception: e, exceptionKind: CommandExceptionKind.Unknown } ); } })(); @@ -121,7 +121,10 @@ defineInterfaceCommand({ try { await this.mjolnir.client.leaveRoom(roomID.toRoomIdOrAlias()); } catch (exception) { - return CommandException.Result(`Failed to leave ${roomRef.toPermalink()} - the room is no longer being protected, but the bot could not leave.`, { exception }); + return CommandException.Result( + `Failed to leave ${roomRef.toPermalink()} - the room is no longer being protected, but the bot could not leave.`, + { exceptionKind: CommandExceptionKind.Unknown, exception } + ); } return CommandResult.Ok(undefined); }, diff --git a/src/commands/interface-manager/CommandException.ts b/src/commands/interface-manager/CommandException.ts index ba8ee132..2dfa8ec2 100644 --- a/src/commands/interface-manager/CommandException.ts +++ b/src/commands/interface-manager/CommandException.ts @@ -5,6 +5,22 @@ import { randomUUID } from "crypto"; import { CommandError, CommandResult } from "./Validation"; +import { LogService } from "matrix-bot-sdk"; + +export enum CommandExceptionKind { + /** + * This class is for exceptions that need to be reported to the user, + * but are mostly irrelevant to the developers because the behaviour is well + * understood and expected. These exceptions will never be logged to the error + * level. + */ + Known = 'Known', + /** + * This class is to be used for reporting unexpected or unknown exceptions + * that the developers need to know about. + */ + Unknown = 'Unknown', +} // FIXME: I wonder if we could allow message to be JSX? // Then room references could be put into the DM and actually mean something. @@ -12,12 +28,22 @@ export class CommandException extends CommandError { public readonly uuid = randomUUID(); constructor( + public readonly exceptionKind: CommandExceptionKind, public readonly exception: Error|unknown, message: string) { super(message) } - public static Result(message: string, options: { exception: Error }): CommandResult { - return CommandResult.Err(new CommandException(options.exception, message)); + public static Result(message: string, options: { exception: Error, exceptionKind: CommandExceptionKind }): CommandResult { + return CommandResult.Err(new CommandException(options.exceptionKind, options.exception, message)); + } + + protected log(): void { + const logArguments: Parameters = ["CommandException", this.exceptionKind, this.uuid, this.message, this.exception]; + if (this.exceptionKind === CommandExceptionKind.Known) { + LogService.info(...logArguments); + } else { + LogService.error(...logArguments); + } } } diff --git a/src/commands/interface-manager/Validation.ts b/src/commands/interface-manager/Validation.ts index 7ee60a31..65582ab6 100644 --- a/src/commands/interface-manager/Validation.ts +++ b/src/commands/interface-manager/Validation.ts @@ -24,6 +24,7 @@ limitations under the License. * However, this file is modified and the modifications in this file * are NOT distributed, contributed, committed, or licensed under the Apache License. */ +import { LogService } from "matrix-bot-sdk"; type ValidationMatchExpression = { ok?: (ok: Ok) => any, err?: (err: Err) => any}; @@ -89,7 +90,7 @@ export class CommandError { public constructor( public readonly message: string, ) { - + this.log(); } /** @@ -101,4 +102,8 @@ export class CommandError { public static Result(message: string, _options = {}): CommandResult { return CommandResult.Err(new CommandError(message)); } + + protected log(): void { + LogService.info("CommandError", this.message); + } } From 9d841697b2ed047352b7d11ad2ea11331a70cbaa Mon Sep 17 00:00:00 2001 From: gnuxie Date: Tue, 5 Sep 2023 18:05:25 +0100 Subject: [PATCH 09/23] Rework RoomUpdateErrors to be CommandErrors or CommandExceptions https://github.com/Gnuxie/Draupnir/pull/93/ --- src/ProtectedRoomsSet.ts | 53 ++++++++++++++-------------- src/models/RoomUpdateError.tsx | 46 ++++++++++++++++++------ src/protections/BanPropagation.tsx | 18 +++++----- src/protections/ProtectionManager.ts | 51 ++++++++------------------ src/queues/EventRedactionQueue.ts | 28 +++++++-------- 5 files changed, 97 insertions(+), 99 deletions(-) diff --git a/src/ProtectedRoomsSet.ts b/src/ProtectedRoomsSet.ts index 6d2cfad0..0bddbd3e 100644 --- a/src/ProtectedRoomsSet.ts +++ b/src/ProtectedRoomsSet.ts @@ -25,14 +25,15 @@ limitations under the License. * are NOT distributed, contributed, committed, or licensed under the Apache License. */ -import { LogLevel, LogService, MatrixGlob, UserID } from "matrix-bot-sdk"; +import { LogLevel, MatrixGlob, UserID } from "matrix-bot-sdk"; +import { CommandExceptionKind } from "./commands/interface-manager/CommandException"; import { IConfig } from "./config"; import ManagementRoomOutput from "./ManagementRoomOutput"; import { MatrixSendClient } from "./MatrixEmitter"; import AccessControlUnit, { Access } from "./models/AccessControlUnit"; import { RULE_ROOM, RULE_SERVER, RULE_USER } from "./models/ListRule"; import PolicyList, { ListRuleChange, Revision } from "./models/PolicyList"; -import { ERROR_KIND_FATAL, ERROR_KIND_PERMISSION, printActionResult, RoomUpdateError } from "./models/RoomUpdateError"; +import { printActionResult, IRoomUpdateError, RoomUpdateException } from "./models/RoomUpdateError"; import { ProtectionManager } from "./protections/ProtectionManager"; import { EventRedactionQueue, RedactUserInRoom } from "./queues/EventRedactionQueue"; import { ProtectedRoomActivityTracker } from "./queues/ProtectedRoomActivityTracker"; @@ -181,7 +182,7 @@ export class ProtectedRoomsSet { * @param roomId Limit processing to one room only, otherwise process redactions for all rooms. * @returns The list of errors encountered, for reporting to the management room. */ - public async processRedactionQueue(roomId?: string): Promise { + public async processRedactionQueue(roomId?: string): Promise { return await this.eventRedactionQueue.process(this.client, this.managementRoomOutput, roomId); } @@ -290,7 +291,7 @@ export class ProtectedRoomsSet { * @param {string[]} roomIds The room IDs to apply the ACLs in. * @param {Mjolnir} mjolnir The Mjolnir client to apply the ACLs with. */ - private async applyServerAcls(lists: PolicyList[], roomIds: string[]): Promise { + private async applyServerAcls(lists: PolicyList[], roomIds: string[]): Promise { // we need to provide mutual exclusion so that we do not have requests updating the m.room.server_acl event // finish out of order and therefore leave the room out of sync with the policy lists. if (this.config.disableServerACL) { @@ -303,7 +304,7 @@ export class ProtectedRoomsSet { }); } - private async _applyServerAcls(lists: PolicyList[], roomIds: string[]): Promise { + private async _applyServerAcls(lists: PolicyList[], roomIds: string[]): Promise { const serverName: string = new UserID(await this.client.getUserId()).domain; // Construct a server ACL first @@ -315,7 +316,7 @@ export class ProtectedRoomsSet { await this.client.sendNotice(this.managementRoomId, `Constructed server ACL:\n${JSON.stringify(finalAcl, null, 2)}`); } - const errors: RoomUpdateError[] = []; + const errors: IRoomUpdateError[] = []; for (const roomId of roomIds) { try { await this.managementRoomOutput.logMessage(LogLevel.DEBUG, "ApplyAcl", `Checking ACLs for ${roomId}`, roomId); @@ -340,8 +341,8 @@ export class ProtectedRoomsSet { } } catch (e) { const message = e.message || (e.body ? e.body.error : ''); - const kind = message && message.includes("You don't have permission to post that to the room") ? ERROR_KIND_PERMISSION : ERROR_KIND_FATAL; - errors.push({ roomId, errorMessage: message, errorKind: kind }); + const kind = message && message.includes("You don't have permission to post that to the room") ? CommandExceptionKind.Known : CommandExceptionKind.Unknown; + errors.push(new RoomUpdateException(roomId, kind, e, message)) } } return errors; @@ -353,17 +354,18 @@ export class ProtectedRoomsSet { * @param {string[]} roomIds The room IDs to apply the bans in. * @param {Mjolnir} mjolnir The Mjolnir client to apply the bans with. */ - private async applyUserBans(roomIds: string[]): Promise { + private async applyUserBans(roomIds: string[]): Promise { // We can only ban people who are not already banned, and who match the rules. - const errors: RoomUpdateError[] = []; + const errors: IRoomUpdateError[] = []; const addErrorToReport = (roomId: string, e: any) => { const message = e.message || (e.body ? e.body.error : ''); - errors.push({ + errors.push(new RoomUpdateException( roomId, - errorMessage: message, - errorKind: message && message.includes("You don't have permission to ban") ? ERROR_KIND_PERMISSION : ERROR_KIND_FATAL, - }); + message && message.includes("You don't have permission to ban") ? CommandExceptionKind.Known : CommandExceptionKind.Unknown, + e, + message + )); }; for (const roomId of roomIds) { @@ -461,28 +463,25 @@ export class ProtectedRoomsSet { } private async printActionResult( - errors: RoomUpdateError[], + errors: IRoomUpdateError[], renderOptions: { title?: string, noErrorsText?: string } ): Promise { printActionResult(this.client, this.managementRoomId, errors, renderOptions); } - public async unbanUser(user: string): Promise { - const errors: RoomUpdateError[] = []; + public async unbanUser(user: string): Promise { + const errors: IRoomUpdateError[] = []; for (const room of this.protectedRoomActivityTracker.protectedRoomsByActivity()) { try { await this.client.unbanUser(user, room); } catch (e) { - // FIXME: We need to know if `info` is acceptable or not. - // Technically these kinds of errors are expected to occur, - // so not sure if it warrants reporting as ERROR. - LogService.info('ProtectedRoomSet', `Unable to unban a user ${user} from ${room}`, e); const message = e.message || (e.body ? e.body.error : ''); - errors.push({ - roomId: room, - errorMessage: message, - errorKind: message && message.includes("You don't have permission to ban") ? ERROR_KIND_PERMISSION : ERROR_KIND_FATAL, - }); + errors.push(new RoomUpdateException( + room, + message && message.includes("You don't have permission to ban") ? CommandExceptionKind.Known : CommandExceptionKind.Unknown, + e, + message + )); } } return errors; @@ -493,7 +492,7 @@ export class ProtectedRoomsSet { } public async verifyPermissions() { - const errors: RoomUpdateError[] = []; + const errors: IRoomUpdateError[] = []; for (const roomId of this.protectedRooms) { errors.push(...(await this.protectionManager.verifyPermissionsIn(roomId))); } diff --git a/src/models/RoomUpdateError.tsx b/src/models/RoomUpdateError.tsx index 01388eb5..c98e2ba7 100644 --- a/src/models/RoomUpdateError.tsx +++ b/src/models/RoomUpdateError.tsx @@ -26,24 +26,48 @@ limitations under the License. */ import { UserID } from "matrix-bot-sdk"; +import { CommandException, CommandExceptionKind } from "../commands/interface-manager/CommandException"; import { DocumentNode } from "../commands/interface-manager/DeadDocument"; import { renderMatrixAndSend } from "../commands/interface-manager/DeadDocumentMatrix"; import { JSXFactory } from "../commands/interface-manager/JSXFactory"; import { Permalinks } from "../commands/interface-manager/Permalinks"; +import { CommandError, CommandResult } from "../commands/interface-manager/Validation"; import { MatrixSendClient } from "../MatrixEmitter"; -export const ERROR_KIND_PERMISSION = "permission"; -export const ERROR_KIND_FATAL = "fatal"; - -export interface RoomUpdateError { - roomId: string; - errorMessage: string; - errorKind: string; +export interface IRoomUpdateError extends CommandError { + readonly roomId: string, } -function renderErrorItem(error: RoomUpdateError, viaServers: string[]): DocumentNode { +export class PermissionError extends CommandError implements IRoomUpdateError { + constructor( + public readonly roomId: string, + message: string + ) { + super(message); + } +} + +export class RoomUpdateException extends CommandException implements IRoomUpdateError { + roomId: string; + + constructor(public readonly: string, ...args: ConstructorParameters) { + super(...args); + } + + public static Result( + message: string, + options: { + exception: Error, + exceptionKind: CommandExceptionKind, + roomId: string + }): CommandResult { + return CommandResult.Err(new RoomUpdateException(options.roomId, options.exceptionKind, options.exception, message)); + } +} + +function renderErrorItem(error: IRoomUpdateError, viaServers: string[]): DocumentNode { return
  • - {error.roomId} - {error.errorMessage} + {error.roomId} - {error.message}
  • } @@ -58,7 +82,7 @@ function renderErrorItem(error: RoomUpdateError, viaServers: string[]): Document */ export async function renderActionResult( client: MatrixSendClient, - errors: RoomUpdateError[], + errors: IRoomUpdateError[], { title = 'There were errors updating protected rooms.', noErrorsText = 'Done updating rooms - no errors.'}: { title?: string, noErrorsText?: string } = {} ): Promise { if (errors.length === 0) { @@ -97,7 +121,7 @@ export async function renderActionResult( export async function printActionResult( client: MatrixSendClient, roomId: string, - errors: RoomUpdateError[], + errors: IRoomUpdateError[], renderOptions: { title?: string, noErrorsText?: string } = {} ): Promise { await renderMatrixAndSend( diff --git a/src/protections/BanPropagation.tsx b/src/protections/BanPropagation.tsx index 46fb4d05..432387a9 100644 --- a/src/protections/BanPropagation.tsx +++ b/src/protections/BanPropagation.tsx @@ -40,7 +40,8 @@ import { MatrixRoomReference } from "../commands/interface-manager/MatrixRoomRef import { findPolicyListFromRoomReference } from "../commands/Ban"; import PolicyList from "../models/PolicyList"; import { renderListRules } from "../commands/Rules"; -import { ERROR_KIND_FATAL, ERROR_KIND_PERMISSION, printActionResult, RoomUpdateError } from "../models/RoomUpdateError"; +import { printActionResult, IRoomUpdateError, RoomUpdateException } from "../models/RoomUpdateError"; +import { CommandExceptionKind } from "../commands/interface-manager/CommandException"; const BAN_PROPAGATION_PROMPT_LISTENER = 'ge.applied-langua.ge.draupnir.ban_propagation'; const UNBAN_PROPAGATION_PROMPT_LISTENER = 'ge.applied-langua.ge.draupnir.unban_propagation'; @@ -157,19 +158,20 @@ async function banReactionListener(this: ListenerContext, key: string, item: unk } } -async function unbanFromAllLists(mjolnir: Mjolnir, user: string): Promise { - const errors: RoomUpdateError[] = []; +async function unbanFromAllLists(mjolnir: Mjolnir, user: string): Promise { + const errors: IRoomUpdateError[] = []; for (const list of mjolnir.policyListManager.lists) { try { await list.unbanEntity(RULE_USER, user); } catch (e) { LogService.info('BanPropagation', `Could not unban ${user} from ${list.roomRef}`, e); const message = e.message || (e.body ? e.body.error : ''); - errors.push({ - roomId: list.roomId, - errorMessage: message, - errorKind: message.includes("You don't have permission") ? ERROR_KIND_PERMISSION : ERROR_KIND_FATAL - }) + errors.push(new RoomUpdateException( + list.roomId, + message.includes("You don't have permission") ? CommandExceptionKind.Known : CommandExceptionKind.Unknown, + e, + message + )); } } return errors; diff --git a/src/protections/ProtectionManager.ts b/src/protections/ProtectionManager.ts index c422f8a1..66ef815d 100644 --- a/src/protections/ProtectionManager.ts +++ b/src/protections/ProtectionManager.ts @@ -39,11 +39,11 @@ import { LogLevel, LogService } from "matrix-bot-sdk"; import { ProtectionSettingValidationError } from "./ProtectionSettings"; import { Consequence } from "./consequence"; import { htmlEscape } from "../utils"; -import { ERROR_KIND_FATAL, ERROR_KIND_PERMISSION } from "../models/RoomUpdateError"; -import { RoomUpdateError } from "../models/RoomUpdateError"; +import { IRoomUpdateError, PermissionError, RoomUpdateException } from "../models/RoomUpdateError"; import { BanPropagation } from "./BanPropagation"; import { MatrixDataManager, RawSchemedData, SchemaMigration, SCHEMA_VERSION_KEY } from "../models/MatrixDataManager"; import { Permalinks } from "../commands/interface-manager/Permalinks"; +import { CommandExceptionKind } from "../commands/interface-manager/CommandException"; const PROTECTIONS: Protection[] = [ new FirstMessageIsImage(), @@ -384,8 +384,8 @@ export class ProtectionManager { return new Set(this.enabledProtections.map((p) => p.requiredStatePermissions).flat()) } - public async verifyPermissionsIn(roomId: string): Promise { - const errors: RoomUpdateError[] = []; + public async verifyPermissionsIn(roomId: string): Promise { + const errors: IRoomUpdateError[] = []; const additionalPermissions = this.requiredProtectionPermissions(); try { @@ -413,35 +413,21 @@ export class ProtectionManager { const userLevel = plDefault(users[ownUserId], usersDefault); const aclLevel = plDefault(events["m.room.server_acl"], stateDefault); - // Wants: ban, kick, redact, m.room.server_acl + const addErrorToReport = (message: string) => { + errors.push(new PermissionError(roomId, message)) + } if (userLevel < ban) { - errors.push({ - roomId, - errorMessage: `Missing power level for bans: ${userLevel} < ${ban}`, - errorKind: ERROR_KIND_PERMISSION, - }); + addErrorToReport(`Missing power level for bans: ${userLevel} < ${ban}`); } if (userLevel < kick) { - errors.push({ - roomId, - errorMessage: `Missing power level for kicks: ${userLevel} < ${kick}`, - errorKind: ERROR_KIND_PERMISSION, - }); + addErrorToReport(`Missing power level for kicks: ${userLevel} < ${kick}`); } if (userLevel < redact) { - errors.push({ - roomId, - errorMessage: `Missing power level for redactions: ${userLevel} < ${redact}`, - errorKind: ERROR_KIND_PERMISSION, - }); + addErrorToReport(`Missing power level for redactions: ${userLevel} < ${redact}`); } if (!this.mjolnir.config.disableServerACL && userLevel < aclLevel) { - errors.push({ - roomId, - errorMessage: `Missing power level for server ACLs: ${userLevel} < ${aclLevel}`, - errorKind: ERROR_KIND_PERMISSION, - }); + addErrorToReport(`Missing power level for server ACLs: ${userLevel} < ${aclLevel}`); } // Wants: Additional permissions @@ -450,24 +436,15 @@ export class ProtectionManager { const permLevel = plDefault(events[additionalPermission], stateDefault); if (userLevel < permLevel) { - errors.push({ - roomId, - errorMessage: `Missing power level for "${additionalPermission}" state events: ${userLevel} < ${permLevel}`, - errorKind: ERROR_KIND_PERMISSION, - }); + addErrorToReport(`Missing power level for "${additionalPermission}" state events: ${userLevel} < ${permLevel}`); } } // Otherwise OK } catch (e) { - LogService.error("Mjolnir", e); - errors.push({ - roomId, - errorMessage: e.message || (e.body ? e.body.error : ''), - errorKind: ERROR_KIND_FATAL, - }); + const message = `Unexpected error when attempting to verify the permissions in ${roomId}`; + errors.push(new RoomUpdateException(roomId, CommandExceptionKind.Unknown, e, message)); } - return errors; } diff --git a/src/queues/EventRedactionQueue.ts b/src/queues/EventRedactionQueue.ts index 2a6d6f3b..8806921f 100644 --- a/src/queues/EventRedactionQueue.ts +++ b/src/queues/EventRedactionQueue.ts @@ -25,11 +25,11 @@ limitations under the License. * are NOT distributed, contributed, committed, or licensed under the Apache License. */ import { LogLevel, MatrixClient } from "matrix-bot-sdk" -import { ERROR_KIND_FATAL } from "../models/RoomUpdateError"; -import { RoomUpdateError } from "../models/RoomUpdateError"; +import { IRoomUpdateError, RoomUpdateException } from "../models/RoomUpdateError"; import { redactUserMessagesIn } from "../utils"; import ManagementRoomOutput from "../ManagementRoomOutput"; import { MatrixSendClient } from "../MatrixEmitter"; +import { CommandExceptionKind } from "../commands/interface-manager/CommandException"; export interface QueuedRedaction { /** The room which the redaction will take place in. */ @@ -119,25 +119,21 @@ export class EventRedactionQueue { * @param limitToRoomId If the roomId is provided, only redactions for that room will be processed. * @returns A description of any errors encountered by each QueuedRedaction that was processed. */ - public async process(client: MatrixSendClient, managementRoom: ManagementRoomOutput, limitToRoomId?: string): Promise { - const errors: RoomUpdateError[] = []; + public async process(client: MatrixSendClient, managementRoom: ManagementRoomOutput, limitToRoomId?: string): Promise { + const errors: IRoomUpdateError[] = []; const redact = async (currentBatch: QueuedRedaction[]) => { for (const redaction of currentBatch) { try { await redaction.redact(client, managementRoom); } catch (e) { - let roomError: RoomUpdateError; - if (e.roomId && e.errorMessage && e.errorKind) { - roomError = e; - } else { - const message = e.message || (e.body ? e.body.error : ''); - roomError = { - roomId: redaction.roomId, - errorMessage: message, - errorKind: ERROR_KIND_FATAL, - }; - } - errors.push(roomError); + const message = e.message || (e.body ? e.body.error : ''); + const error = new RoomUpdateException( + redaction.roomId, + CommandExceptionKind.Unknown, + e, + message + ); + errors.push(error); } } } From bef21850e8bdd4b2dab9c2f5ee8b29c93fa61ee6 Mon Sep 17 00:00:00 2001 From: Gnuxie <50846879+Gnuxie@users.noreply.github.com> Date: Thu, 7 Sep 2023 14:13:26 +0100 Subject: [PATCH 10/23] Use `--forbid-only` flag in integration test suite. (#97) Yes this has happened again, at least we know how to fix it now. --- README.md | 2 ++ package.json | 4 ++-- test/integration/banListTest.ts | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e8cb5b6b..382de1be 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,8 @@ As Draupnir heads towards `v2.0.0`, releases will appear [here](https://github.c Until `v2.0.0` there will be frequent changes to commands but all of these will be noted in the changes for that release. +### Migration + Migrating from Mjolnir is straightforward and requires no manual steps, migration for your setup is likely as simple as changing your server config to pull the latest Draupnir docker image instead of a mjolnir one. diff --git a/package.json b/package.json index 507485ea..f3059ad9 100644 --- a/package.json +++ b/package.json @@ -15,9 +15,9 @@ "lint": "tslint --project ./tsconfig.json -t stylish", "start:dev": "yarn build && node --async-stack-traces lib/index.js", "test": "ts-mocha --project ./tsconfig.json test/commands/**/*.ts", - "test:integration": "NODE_ENV=harness ts-mocha --async-stack-traces --require test/integration/fixtures.ts --timeout 300000 --project ./tsconfig.json \"test/integration/**/*Test.ts\"", + "test:integration": "NODE_ENV=harness ts-mocha --async-stack-traces --forbid-only --require test/integration/fixtures.ts --timeout 300000 --project ./tsconfig.json \"test/integration/**/*Test.ts\"", "test:integration:single": "NODE_ENV=harness npx ts-mocha --require test/integration/fixtures.ts --timeout 300000 --project ./tsconfig.json", - "test:appservice:integration": "NODE_ENV=harness ts-mocha --async-stack-traces --timeout 300000 --project ./tsconfig.json \"test/appservice/integration/**/*Test.ts\"", + "test:appservice:integration": "NODE_ENV=harness ts-mocha --async-stack-traces --forbid-only --timeout 300000 --project ./tsconfig.json \"test/appservice/integration/**/*Test.ts\"", "test:appservice:integration:single": "NODE_ENV=harness npx ts-mocha --timeout 300000 --project ./tsconfig.json", "test:manual": "NODE_ENV=harness ts-node test/integration/manualLaunchScript.ts", "version": "sed -i '/# version automated/s/[0-9][0-9]*\\.[0-9][0-9]*\\.[0-9][^\"]*/'$npm_package_version'/' synapse_antispam/setup.py && git add synapse_antispam/setup.py && cat synapse_antispam/setup.py" diff --git a/test/integration/banListTest.ts b/test/integration/banListTest.ts index 5bfca29c..a0320720 100644 --- a/test/integration/banListTest.ts +++ b/test/integration/banListTest.ts @@ -597,7 +597,7 @@ describe('Test: Creating policy lists.', function() { }) }) -describe.only('Test: Continue to ban other marked members when one member cannot be banned', function() { +describe('Test: Continue to ban other marked members when one member cannot be banned', function() { it('Failing to ban a moderator should not stop other members being banned.', async function(this: MjolnirTestContext) { if (this.mjolnir === undefined) { throw new TypeError("Mjolnir was never created.") From 4b656306edfc3234fafd3149a80396a5f456af39 Mon Sep 17 00:00:00 2001 From: Gnuxie <50846879+Gnuxie@users.noreply.github.com> Date: Thu, 7 Sep 2023 15:27:00 +0100 Subject: [PATCH 11/23] Deprecate `config.verboseLogging` (#98) Shouldn't change what is being logged to the log file, but it does change what gets sent to the management room. I've been meaning to disable this for some time as it generally confuses new users and it makes the bot feel very confusing and low quality. It also means you are likely to miss more important messages in the magement room. Another problem it causes is an inconsistent view when testing the software and it's an unreasonable burden to test for both settings. It's not clear what the value of this setting is apart from providing comfort to some users who want to see the ACL readout. But even then it's a very inefficient way of doing that, so i'd rather another feature be requested by users that want to see that. --- config/default.yaml | 4 +++- config/harness.yaml | 8 ++++++-- src/Mjolnir.ts | 3 +++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/config/default.yaml b/config/default.yaml index d3783abc..a90b6d38 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -51,9 +51,11 @@ recordIgnoredInvites: false # (see verboseLogging to adjust this a bit.) managementRoom: "#moderators:example.org" +# Deprecated and will be removed in a future version. +# Running with verboseLogging is unsupported. # Whether Draupnir should log a lot more messages in the room, # mainly involves "all-OK" messages, and debugging messages for when draupnir checks bans in a room. -verboseLogging: true +verboseLogging: false # The log level of terminal (or container) output, # can be one of DEBUG, INFO, WARN and ERROR, in increasing order of importance and severity. diff --git a/config/harness.yaml b/config/harness.yaml index 18b992fa..9e9303d5 100644 --- a/config/harness.yaml +++ b/config/harness.yaml @@ -47,8 +47,12 @@ recordIgnoredInvites: false # Note: Mjolnir is fairly verbose - expect a lot of messages from it. managementRoom: "#moderators:localhost:9999" -# Set to false to make the management room a bit quieter. -verboseLogging: true +# Deprecated and will be removed in a future version. +# Running with verboseLogging is unsupported. +# Whether Draupnir should log a lot more messages in the room, +# mainly involves "all-OK" messages, and debugging messages for when draupnir checks bans in a room. +verboseLogging: false + # The log level for the logs themselves. One of DEBUG, INFO, WARN, and ERROR. # This should be at INFO or DEBUG in order to get support for Mjolnir problems. diff --git a/src/Mjolnir.ts b/src/Mjolnir.ts index 1533f5d3..603f60b8 100644 --- a/src/Mjolnir.ts +++ b/src/Mjolnir.ts @@ -336,6 +336,9 @@ export class Mjolnir { this.currentState = STATE_RUNNING; await this.managementRoomOutput.logMessage(LogLevel.INFO, "Mjolnir@startup", "Startup complete. Now monitoring rooms."); + if (this.config.verboseLogging) { + await this.managementRoomOutput.logMessage(LogLevel.WARN, "Mjolnir@startup", "The use of verbose logging is deprecated and will be removed in a future version, check your config."); + } } catch (err) { try { LogService.error("Mjolnir", "Error during startup:", err); From 26468afcde7ef80c5e600b917cd48ddfa7c70524 Mon Sep 17 00:00:00 2001 From: Gnuxie <50846879+Gnuxie@users.noreply.github.com> Date: Thu, 7 Sep 2023 15:59:20 +0100 Subject: [PATCH 12/23] Only CommandExceptions should log at creation. (#99) Before CommandError's where and they are used liberally for validating command arguments by returning a CommandResult for several possible options. Which gives a lot of spam. It's not necessary anyways since these should only be used for known errors. --- src/commands/interface-manager/CommandException.ts | 1 + src/commands/interface-manager/Validation.ts | 7 +------ 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/commands/interface-manager/CommandException.ts b/src/commands/interface-manager/CommandException.ts index 2dfa8ec2..88f00b33 100644 --- a/src/commands/interface-manager/CommandException.ts +++ b/src/commands/interface-manager/CommandException.ts @@ -32,6 +32,7 @@ export class CommandException extends CommandError { public readonly exception: Error|unknown, message: string) { super(message) + this.log(); } public static Result(message: string, options: { exception: Error, exceptionKind: CommandExceptionKind }): CommandResult { diff --git a/src/commands/interface-manager/Validation.ts b/src/commands/interface-manager/Validation.ts index 65582ab6..3d17bd33 100644 --- a/src/commands/interface-manager/Validation.ts +++ b/src/commands/interface-manager/Validation.ts @@ -24,7 +24,6 @@ limitations under the License. * However, this file is modified and the modifications in this file * are NOT distributed, contributed, committed, or licensed under the Apache License. */ -import { LogService } from "matrix-bot-sdk"; type ValidationMatchExpression = { ok?: (ok: Ok) => any, err?: (err: Err) => any}; @@ -90,7 +89,7 @@ export class CommandError { public constructor( public readonly message: string, ) { - this.log(); + // nothing to do. } /** @@ -102,8 +101,4 @@ export class CommandError { public static Result(message: string, _options = {}): CommandResult { return CommandResult.Err(new CommandError(message)); } - - protected log(): void { - LogService.info("CommandError", this.message); - } } From fb0199fdc98c568091b410c32bbd95ac99785aca Mon Sep 17 00:00:00 2001 From: gnuxie Date: Thu, 7 Sep 2023 16:00:02 +0100 Subject: [PATCH 13/23] v1.85.0 --- package.json | 2 +- synapse_antispam/setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index f3059ad9..bc337fbf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "draupnir", - "version": "1.84.0", + "version": "1.85.0", "description": "A moderation tool for Matrix", "main": "lib/index.js", "repository": "https://github.com/Gnuxie/Draupnir.git", diff --git a/synapse_antispam/setup.py b/synapse_antispam/setup.py index dd7ec4a3..20d00d5a 100644 --- a/synapse_antispam/setup.py +++ b/synapse_antispam/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name="mjolnir", - version="1.84.0", # version automated in package.json - Do not edit this line, use `yarn version`. + version="1.85.0", # version automated in package.json - Do not edit this line, use `yarn version`. packages=find_packages(), description="Mjolnir Antispam", include_package_data=True, From 645dd8950f7b2adce3a97a77c95bcccd10af748a Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 11 Sep 2023 12:08:16 +0200 Subject: [PATCH 14/23] Upgrade matrix-appservice bridge to ^9.0.1 (#102) --- package.json | 2 +- yarn.lock | 128 +++++++++++++++++++++++++++++++++------------------ 2 files changed, 85 insertions(+), 45 deletions(-) diff --git a/package.json b/package.json index bc337fbf..1109f5c7 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "humanize-duration-ts": "^2.1.1", "js-yaml": "^4.1.0", "jsdom": "^16.6.0", - "matrix-appservice-bridge": "8.1.2", + "matrix-appservice-bridge": "^9.0.1", "parse-duration": "^1.0.2", "pg": "^8.8.0", "shell-quote": "^1.7.3", diff --git a/yarn.lock b/yarn.lock index e4881940..5e8ecf51 100644 --- a/yarn.lock +++ b/yarn.lock @@ -89,12 +89,13 @@ "@types/yargs" "^16.0.0" chalk "^4.0.0" -"@matrix-org/matrix-sdk-crypto-nodejs@^0.1.0-beta.1": - version "0.1.0-beta.1" - resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-nodejs/-/matrix-sdk-crypto-nodejs-0.1.0-beta.1.tgz#8a9058226916a258e5b4e28d76680e895b6203b2" - integrity sha512-jCSKrmNh6kaqnOwS/Pqgqkeb+CAvwGuS0oNEW3LaWKrJWFAfUrt+lXBCs7kAP79Qo5ZKBU06BekbZuwYhWbhkQ== +"@matrix-org/matrix-sdk-crypto-nodejs@0.1.0-beta.6": + version "0.1.0-beta.6" + resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-nodejs/-/matrix-sdk-crypto-nodejs-0.1.0-beta.6.tgz#0ecae51103ee3c107af0d6d0738f33eb7cc9857e" + integrity sha512-JXyrHuCVMydUGgSetWsfqbbvHj3aUMOX5TUghlMtLFromyEu7wIsNgYt7PjJ+k3WdF4GVABRy4P6GNjaEMy2uA== dependencies: - node-downloader-helper "^2.1.1" + https-proxy-agent "^5.0.1" + node-downloader-helper "^2.1.5" "@selderee/plugin-htmlparser2@^0.6.0": version "0.6.0" @@ -193,7 +194,7 @@ "@types/qs" "*" "@types/range-parser" "*" -"@types/express@^4.17.13", "@types/express@^4.17.8": +"@types/express@^4.17.13": version "4.17.13" resolved "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz" integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== @@ -292,13 +293,6 @@ pg-protocol "*" pg-types "^2.2.0" -"@types/pkginfo@^0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@types/pkginfo/-/pkginfo-0.4.0.tgz#00143b97e98aa7c9391943266d2e4aebd8f44c35" - integrity sha512-4DGKkOlWkMuVDZQvytWzzWWAjyqDmlLKRYE4lzeA8t0s7fK0aF25uPbX9eBVermUjLJdeLHu9k1WmNiAssqCcg== - dependencies: - "@types/node" "*" - "@types/qs@*": version "6.9.7" resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz" @@ -988,7 +982,16 @@ dom-serializer@^1.0.1: domhandler "^4.2.0" entities "^2.0.0" -domelementtype@^2.0.1, domelementtype@^2.2.0: +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + +domelementtype@^2.0.1, domelementtype@^2.2.0, domelementtype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== @@ -1007,6 +1010,13 @@ domhandler@^4.0.0, domhandler@^4.2.0: dependencies: domelementtype "^2.2.0" +domhandler@^5.0.2, domhandler@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + domutils@^2.5.2: version "2.8.0" resolved "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz" @@ -1016,6 +1026,15 @@ domutils@^2.5.2: domelementtype "^2.2.0" domhandler "^4.2.0" +domutils@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.1.0.tgz#c47f551278d3dc4b0b1ab8cbb42d751a6f0d824e" + integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" @@ -1066,6 +1085,11 @@ entities@^2.0.0: resolved "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== +entities@^4.2.0, entities@^4.4.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + escalade@^3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" @@ -1244,7 +1268,7 @@ express-rate-limit@^6.7.0: resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-6.7.0.tgz#6aa8a1bd63dfe79702267b3af1161a93afc1d3c2" integrity sha512-vhwIdRoqcYB/72TK3tRZI+0ttS8Ytrk24GfmsxDXK9o9IhHNO5bXRiXQSExPQ4GbaE5tvIS7j1SGrxsuWs+sGA== -express@^4.17, express@^4.17.1, express@^4.18.1: +express@^4.17, express@^4.18.1: version "4.18.1" resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== @@ -1634,7 +1658,7 @@ htmlencode@^0.0.4: resolved "https://registry.yarnpkg.com/htmlencode/-/htmlencode-0.0.4.tgz#f7e2d6afbe18a87a78e63ba3308e753766740e3f" integrity sha512-0uDvNVpzj/E2TfvLLyyXhKBRvF1y84aZsyRxRXFsQobnHaL4pcaXk+Y9cnFlvnxrBLeXDNq/VJBD+ngdBgQG1w== -htmlparser2@^6.0.0, htmlparser2@^6.1.0: +htmlparser2@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== @@ -1644,6 +1668,16 @@ htmlparser2@^6.0.0, htmlparser2@^6.1.0: domutils "^2.5.2" entities "^2.0.0" +htmlparser2@^8.0.0: + version "8.0.2" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.2.tgz#f002151705b383e62433b5cf466f5b716edaec21" + integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.0.1" + entities "^4.4.0" + http-errors@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" @@ -1681,6 +1715,14 @@ https-proxy-agent@^5.0.0: agent-base "6" debug "4" +https-proxy-agent@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + humanize-duration-ts@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/humanize-duration-ts/-/humanize-duration-ts-2.1.1.tgz" @@ -2149,13 +2191,12 @@ make-error@^1.1.1: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== -matrix-appservice-bridge@8.1.2: - version "8.1.2" - resolved "https://registry.yarnpkg.com/matrix-appservice-bridge/-/matrix-appservice-bridge-8.1.2.tgz#30953a4599533fe61a0c37bd5500b654cd236e30" - integrity sha512-OTQVEuYgsnlg7fBFASCaiYHgwi5+I/+vxwjOmR4y9n5ESKXoqI465bN+6zvW8MazdNfBl6NgZVWSm4DZohz8Zw== +matrix-appservice-bridge@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/matrix-appservice-bridge/-/matrix-appservice-bridge-9.0.1.tgz#01db1c821cdecc3f27844fa2452c9dd72a3a75da" + integrity sha512-gmR5hoN51ZFBk4LA1iFW1umxKRy6Iz7UAo32NOh7eJQRmyl6aAM5RWFFiBTHhw1KfBvR/FwKS/sxerbmgmHiXw== dependencies: "@alloc/quick-lru" "^5.2.0" - "@types/pkginfo" "^0.4.0" axios "^0.27.2" chalk "^4.1.0" express "^4.18.1" @@ -2164,8 +2205,8 @@ matrix-appservice-bridge@8.1.2: ip-cidr "^3.0.4" is-my-json-valid "^2.20.5" js-yaml "^4.0.0" - matrix-appservice "^1.1.0" - matrix-bot-sdk "^0.6.2" + matrix-appservice "^2.0.0" + matrix-bot-sdk "npm:@vector-im/matrix-bot-sdk@^0.6.6-element.1" nedb "^1.8.0" nopt "^5.0.0" p-queue "^6.6.2" @@ -2176,23 +2217,22 @@ matrix-appservice-bridge@8.1.2: winston "^3.3.3" winston-daily-rotate-file "^4.5.1" -matrix-appservice@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/matrix-appservice/-/matrix-appservice-1.1.0.tgz#e567945042000485e4ea4bfeef92246e93296f01" - integrity sha512-6hJdmo9YIbh6dS9MfMHCpHMhklN/+NOcfGQ/3UbbEEfIE8dt0bHqi1nnIiias5IqDFl6ED9y+YQdtyqnIXx+Ww== +matrix-appservice@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/matrix-appservice/-/matrix-appservice-2.0.0.tgz#74b58e27477b4c1359da7c61878b7d18c6075261" + integrity sha512-HCIuJ5i0YuO8b0dMyGe5dqlsE4f3RzHU0MuMg/2gGAZ4HL3r7aSWOFbyIWStSSUrk1qCa9Eml0i4EnEi0pOtdA== dependencies: - "@types/express" "^4.17.8" body-parser "^1.19.0" - express "^4.17.1" + express "^4.18.1" js-yaml "^4.1.0" morgan "^1.10.0" -matrix-bot-sdk@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/matrix-bot-sdk/-/matrix-bot-sdk-0.6.2.tgz#c9334b39f62a9742d74e46312def566429dfef26" - integrity sha512-+kXlXkQBQgWC6oUwYEosJlXjceaj7jQUnPlALFhGeAabgVm8tmuvFNVKqClwvrrjj+0Gzsmt+rcJHmkvqymFXA== +"matrix-bot-sdk@npm:@vector-im/matrix-bot-sdk@^0.6.6-element.1": + version "0.6.6" + resolved "https://registry.yarnpkg.com/@vector-im/matrix-bot-sdk/-/matrix-bot-sdk-0.6.6.tgz#e8a29d1404ab07e5d150b98222e9fbfc369752bb" + integrity sha512-MIZDCau+cWij3+NimTGOyVMDKb5EXO5wEEeS47wd+avr4ZN5EUO2pj2MLIytL9UYZ1OSlkZzECU4MRTL5B4wbQ== dependencies: - "@matrix-org/matrix-sdk-crypto-nodejs" "^0.1.0-beta.1" + "@matrix-org/matrix-sdk-crypto-nodejs" "0.1.0-beta.6" "@types/express" "^4.17.13" another-json "^0.2.0" async-lock "^1.3.2" @@ -2208,7 +2248,7 @@ matrix-bot-sdk@^0.6.2: morgan "^1.10.0" request "^2.88.2" request-promise "^4.2.6" - sanitize-html "^2.7.0" + sanitize-html "^2.8.0" media-typer@0.3.0: version "0.3.0" @@ -2400,10 +2440,10 @@ negotiator@0.6.3: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== -node-downloader-helper@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/node-downloader-helper/-/node-downloader-helper-2.1.1.tgz#533427a3cdc163931b106d0fe6d522f83deac7ab" - integrity sha512-ouk8MGmJj1gYymbJwi1L8Mr6PdyheJLwfsmyx0KtsvyJ+7Fpf0kBBzM8Gmx8Mt/JBfRWP1PQm6dAGV6x7eNedw== +node-downloader-helper@^2.1.5: + version "2.1.9" + resolved "https://registry.yarnpkg.com/node-downloader-helper/-/node-downloader-helper-2.1.9.tgz#a59ee7276b2bf708bbac2cc5872ad28fc7cd1b0e" + integrity sha512-FSvAol2Z8UP191sZtsUZwHIN0eGoGue3uEXGdWIH5228e9KH1YHXT7fN8Oa33UGf+FbqGTQg3sJfrRGzmVCaJA== nopt@^5.0.0: version "5.0.0" @@ -2943,14 +2983,14 @@ safe-stable-stringify@^2.3.1: resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sanitize-html@^2.7.0: - version "2.7.1" - resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-2.7.1.tgz#a6c2c1a88054a79eeacfac9b0a43f1b393476901" - integrity sha512-oOpe8l4J8CaBk++2haoN5yNI5beekjuHv3JRPKUx/7h40Rdr85pemn4NkvUB3TcBP7yjat574sPlcMAyv4UQig== +sanitize-html@^2.8.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-2.11.0.tgz#9a6434ee8fcaeddc740d8ae7cd5dd71d3981f8f6" + integrity sha512-BG68EDHRaGKqlsNjJ2xUB7gpInPA8gVx/mvjO743hZaeMCZ2DwzW7xvsqZ+KNU4QKwj86HJ3uu2liISf2qBBUA== dependencies: deepmerge "^4.2.2" escape-string-regexp "^4.0.0" - htmlparser2 "^6.0.0" + htmlparser2 "^8.0.0" is-plain-object "^5.0.0" parse-srcset "^1.0.2" postcss "^8.3.11" From fe7f388d0e98174ca55da69677157c9a80e9bc8b Mon Sep 17 00:00:00 2001 From: Aminda Suomalainen Date: Mon, 11 Sep 2023 13:15:06 +0300 Subject: [PATCH 15/23] .github/dependabot.yml: explicitly configure dependabot (#103) --- .github/dependabot.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..c1d10feb --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +version: 2 +updates: + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "daily" + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" From ee33c9aa18b9f6881972be34213d122b967778ce Mon Sep 17 00:00:00 2001 From: Aminda Suomalainen Date: Mon, 11 Sep 2023 15:28:38 +0300 Subject: [PATCH 16/23] .github/dependabot.yml: attempt to group updates (#114) * .github/dependabot.yml: first attempt at grouping production & development dependencies Resolves: #113 * dependabot: don't group production depedencies * dependabot: group GitHub actions --- .github/dependabot.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index c1d10feb..43f8fdac 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -4,8 +4,15 @@ updates: directory: "/" schedule: interval: "daily" + groups: + development-dependencies: + dependency-type: "development" - package-ecosystem: "github-actions" directory: "/" schedule: interval: "daily" + groups: + everything: + patterns: + - "*" From 0112a995b7d2855bac346fad0e7d76f650a5ea28 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 13:38:45 +0100 Subject: [PATCH 17/23] Bump the development-dependencies group with 9 updates (#116) Bumps the development-dependencies group with 9 updates: | Package | From | To | | --- | --- | --- | | [@types/crypto-js](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/crypto-js) | `4.0.2` | `4.1.2` | | [@types/nedb](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/nedb) | `1.8.12` | `1.8.13` | | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `18.16.7` | `20.6.0` | | [eslint](https://github.com/eslint/eslint) | `7.32.0` | `8.49.0` | | [expect](https://github.com/jestjs/jest/tree/HEAD/packages/expect) | `27.2.4` | `29.6.4` | | [mocha](https://github.com/mochajs/mocha) | `9.2.2` | `10.2.0` | | [@types/mocha](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/mocha) | `9.0.0` | `10.0.1` | | [ts-mocha](https://github.com/piotrwitek/ts-mocha) | `9.0.2` | `10.0.0` | | [typescript](https://github.com/Microsoft/TypeScript) | `5.1.6` | `5.2.2` | Updates `@types/crypto-js` from 4.0.2 to 4.1.2 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/crypto-js) Updates `@types/nedb` from 1.8.12 to 1.8.13 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/nedb) Updates `@types/node` from 18.16.7 to 20.6.0 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Updates `eslint` from 7.32.0 to 8.49.0 - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v7.32.0...v8.49.0) Updates `expect` from 27.2.4 to 29.6.4 - [Release notes](https://github.com/jestjs/jest/releases) - [Changelog](https://github.com/jestjs/jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/jestjs/jest/commits/v29.6.4/packages/expect) Updates `mocha` from 9.2.2 to 10.2.0 - [Release notes](https://github.com/mochajs/mocha/releases) - [Changelog](https://github.com/mochajs/mocha/blob/master/CHANGELOG.md) - [Commits](https://github.com/mochajs/mocha/compare/v9.2.2...v10.2.0) Updates `@types/mocha` from 9.0.0 to 10.0.1 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/mocha) Updates `ts-mocha` from 9.0.2 to 10.0.0 - [Release notes](https://github.com/piotrwitek/ts-mocha/releases) - [Changelog](https://github.com/piotrwitek/ts-mocha/blob/master/CHANGELOG.md) - [Commits](https://github.com/piotrwitek/ts-mocha/commits) Updates `typescript` from 5.1.6 to 5.2.2 - [Release notes](https://github.com/Microsoft/TypeScript/releases) - [Commits](https://github.com/Microsoft/TypeScript/compare/v5.1.6...v5.2.2) --- updated-dependencies: - dependency-name: "@types/crypto-js" dependency-type: direct:development update-type: version-update:semver-minor dependency-group: development-dependencies - dependency-name: "@types/nedb" dependency-type: direct:development update-type: version-update:semver-patch dependency-group: development-dependencies - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-major dependency-group: development-dependencies - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-major dependency-group: development-dependencies - dependency-name: expect dependency-type: direct:development update-type: version-update:semver-major dependency-group: development-dependencies - dependency-name: mocha dependency-type: direct:development update-type: version-update:semver-major dependency-group: development-dependencies - dependency-name: "@types/mocha" dependency-type: direct:development update-type: version-update:semver-major dependency-group: development-dependencies - dependency-name: ts-mocha dependency-type: direct:development update-type: version-update:semver-major dependency-group: development-dependencies - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-minor dependency-group: development-dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 18 +- yarn.lock | 702 +++++++++++++++++++++++++-------------------------- 2 files changed, 352 insertions(+), 368 deletions(-) diff --git a/package.json b/package.json index 1109f5c7..637d75f5 100644 --- a/package.json +++ b/package.json @@ -24,25 +24,25 @@ }, "devDependencies": { "@types/config": "^3.3.0", - "@types/crypto-js": "^4.0.2", + "@types/crypto-js": "^4.1.2", "@types/express": "^4.17.13", "@types/html-to-text": "^8.0.1", "@types/humanize-duration": "^3.27.1", "@types/js-yaml": "^4.0.5", "@types/jsdom": "^16.2.11", - "@types/mocha": "^9.0.0", - "@types/nedb": "^1.8.12", - "@types/node": "^18.16.7", + "@types/mocha": "^10.0.1", + "@types/nedb": "^1.8.13", + "@types/node": "^20.6.0", "@types/pg": "^8.6.5", "@types/request": "^2.48.8", "@types/shell-quote": "1.7.1", "crypto-js": "^4.1.1", - "eslint": "^7.32", - "expect": "^27.0.6", - "mocha": "^9.0.1", - "ts-mocha": "^9.0.2", + "eslint": "^8.49", + "expect": "^29.6.4", + "mocha": "^10.2.0", + "ts-mocha": "^10.0.0", "tslint": "^6.1.3", - "typescript": "^5.1.6", + "typescript": "^5.2.2", "typescript-formatter": "^7.2" }, "dependencies": { diff --git a/yarn.lock b/yarn.lock index 5e8ecf51..344ffc26 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,18 +2,16 @@ # yarn lockfile v1 +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + "@alloc/quick-lru@^5.2.0": version "5.2.0" resolved "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz" integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== -"@babel/code-frame@7.12.11": - version "7.12.11" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz" - integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== - dependencies: - "@babel/highlight" "^7.10.4" - "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13": version "7.14.5" resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz" @@ -26,7 +24,7 @@ resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz" integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== -"@babel/highlight@^7.10.4", "@babel/highlight@^7.14.5": +"@babel/highlight@^7.14.5": version "7.14.5" resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz" integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== @@ -49,44 +47,81 @@ enabled "2.0.x" kuler "^2.0.0" -"@eslint/eslintrc@^0.4.3": - version "0.4.3" - resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz" - integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== +"@eslint-community/eslint-utils@^4.2.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.6.1": + version "4.8.0" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.8.0.tgz#11195513186f68d42fbf449f9a7136b2c0c92005" + integrity sha512-JylOEEzDiOryeUnFbQz+oViCXS0KsvR1mvHkoMiu5+UiBvy+RYX7tzlIIIEstF/gVa2tj9AQXk3dgnxv6KxhFg== + +"@eslint/eslintrc@^2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.2.tgz#c6936b4b328c64496692f76944e755738be62396" + integrity sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g== dependencies: ajv "^6.12.4" - debug "^4.1.1" - espree "^7.3.0" - globals "^13.9.0" - ignore "^4.0.6" + debug "^4.3.2" + espree "^9.6.0" + globals "^13.19.0" + ignore "^5.2.0" import-fresh "^3.2.1" - js-yaml "^3.13.1" - minimatch "^3.0.4" + js-yaml "^4.1.0" + minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@humanwhocodes/config-array@^0.5.0": - version "0.5.0" - resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz" - integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== +"@eslint/js@8.49.0": + version "8.49.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.49.0.tgz#86f79756004a97fa4df866835093f1df3d03c333" + integrity sha512-1S8uAY/MTJqVx0SC4epBq+N2yhuwtNwLbJYNZyhL2pO1ZVKn5HFXav5T41Ryzy9K9V7ZId2JB2oy/W4aCd9/2w== + +"@humanwhocodes/config-array@^0.11.11": + version "0.11.11" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.11.tgz#88a04c570dbbc7dd943e4712429c3df09bc32844" + integrity sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA== dependencies: - "@humanwhocodes/object-schema" "^1.2.0" + "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" - minimatch "^3.0.4" + minimatch "^3.0.5" -"@humanwhocodes/object-schema@^1.2.0": - version "1.2.0" - resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz" - integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== -"@jest/types@^27.2.4": - version "27.2.4" - resolved "https://registry.npmjs.org/@jest/types/-/types-27.2.4.tgz" - integrity sha512-IDO2ezTxeMvQAHxzG/ZvEyA47q0aVfzT95rGFl7bZs/Go0aIucvfDbS2rmnoEdXxlLQhcolmoG/wvL/uKx4tKA== +"@humanwhocodes/object-schema@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + +"@jest/expect-utils@^29.6.4": + version "29.6.4" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.6.4.tgz#17c7dfe6cec106441f218b0aff4b295f98346679" + integrity sha512-FEhkJhqtvBwgSpiTrocquJCdXPsyvNKcl/n7A3u7X4pVoF4bswm11c9d4AV+kfq2Gpv/mM8x7E7DsRvH+djkrg== dependencies: + jest-get-type "^29.6.3" + +"@jest/schemas@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" + integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== + dependencies: + "@sinclair/typebox" "^0.27.8" + +"@jest/types@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" + integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== + dependencies: + "@jest/schemas" "^29.6.3" "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" "@types/node" "*" - "@types/yargs" "^16.0.0" + "@types/yargs" "^17.0.8" chalk "^4.0.0" "@matrix-org/matrix-sdk-crypto-nodejs@0.1.0-beta.6": @@ -97,6 +132,27 @@ https-proxy-agent "^5.0.1" node-downloader-helper "^2.1.5" +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + "@selderee/plugin-htmlparser2@^0.6.0": version "0.6.0" resolved "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.6.0.tgz" @@ -150,6 +206,11 @@ "@sentry/types" "7.22.0" tslib "^1.9.3" +"@sinclair/typebox@^0.27.8": + version "0.27.8" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" + integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== + "@tootallnate/once@1": version "1.1.2" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" @@ -180,10 +241,10 @@ dependencies: "@types/node" "*" -"@types/crypto-js@^4.0.2": - version "4.0.2" - resolved "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.0.2.tgz" - integrity sha512-sCVniU+h3GcGqxOmng11BRvf9TfN9yIs8KKjB8C8d75W69cpTfZG80gau9yTx5SxF3gvHGbJhdESzzvnjtf3Og== +"@types/crypto-js@^4.1.2": + version "4.1.2" + resolved "https://registry.yarnpkg.com/@types/crypto-js/-/crypto-js-4.1.2.tgz#fb56b34f397d9ae2335611e416f15e7d65e276e6" + integrity sha512-t33RNmTu5ufG/sorROIafiCVJMx3jz95bXUMoPAZcUD14fxMXnuTzqzXZoxpR0tNx2xpw11Dlmem9vGCsrSOfA== "@types/express-serve-static-core@^4.17.18": version "4.17.30" @@ -257,27 +318,22 @@ resolved "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz" integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== -"@types/mocha@^9.0.0": - version "9.0.0" - resolved "https://registry.npmjs.org/@types/mocha/-/mocha-9.0.0.tgz" - integrity sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA== +"@types/mocha@^10.0.1": + version "10.0.1" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.1.tgz#2f4f65bb08bc368ac39c96da7b2f09140b26851b" + integrity sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q== -"@types/nedb@^1.8.12": - version "1.8.12" - resolved "https://registry.npmjs.org/@types/nedb/-/nedb-1.8.12.tgz" - integrity sha512-ICDoQMORMjOSqfNFXT4ENXfwwCir1BPblXNm0SPH7C4Q10ou+pvVagcFAJ+rrzf3A47tGU4K/KbzKu7wO9j45Q== +"@types/nedb@^1.8.13": + version "1.8.13" + resolved "https://registry.yarnpkg.com/@types/nedb/-/nedb-1.8.13.tgz#31c608d5b155d33b3c98b946339086703d215865" + integrity sha512-x/aIeHmmiDq1kMzgHvjygxl5RZGzIabFcq2HpRzB3X26AdfPg5Y70EwWrcZM/TuJwNHtWRruD/telSTvPEY6Xw== dependencies: "@types/node" "*" -"@types/node@*": - version "18.6.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.6.1.tgz#828e4785ccca13f44e2fb6852ae0ef11e3e20ba5" - integrity sha512-z+2vB6yDt1fNwKOeGbckpmirO+VBDuQqecXkgeIqDlaOtmKn6hPR/viQ8cxCfqLU4fTlvM3+YjM367TukWdxpg== - -"@types/node@^18.16.7": - version "18.16.7" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.16.7.tgz#86d0ba2541f808cb78d4dc5d3e40242a349d6db8" - integrity sha512-MFg7ua/bRtnA1hYE3pVyWxGd/r7aMqjNOdHvlSsXV3n8iaeGKkOaPzpJh6/ovf4bEXWcojkeMJpTsq3mzXW4IQ== +"@types/node@*", "@types/node@^20.6.0": + version "20.6.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.6.0.tgz#9d7daa855d33d4efec8aea88cd66db1c2f0ebe16" + integrity sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg== "@types/parse5@*": version "6.0.1" @@ -341,18 +397,13 @@ resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz" integrity sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw== -"@types/yargs@^16.0.0": - version "16.0.4" - resolved "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz" - integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw== +"@types/yargs@^17.0.8": + version "17.0.24" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.24.tgz#b3ef8d50ad4aa6aecf6ddc97c580a00f5aa11902" + integrity sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw== dependencies: "@types/yargs-parser" "*" -"@ungap/promise-all-settled@1.1.2": - version "1.1.2" - resolved "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz" - integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== - abab@^2.0.3, abab@^2.0.5: version "2.0.5" resolved "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz" @@ -379,9 +430,9 @@ acorn-globals@^6.0.0: acorn "^7.1.1" acorn-walk "^7.1.1" -acorn-jsx@^5.3.1: +acorn-jsx@^5.3.2: version "5.3.2" - resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn-walk@^7.1.1: @@ -389,7 +440,7 @@ acorn-walk@^7.1.1: resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz" integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== -acorn@^7.1.1, acorn@^7.4.0: +acorn@^7.1.1: version "7.4.1" resolved "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== @@ -399,6 +450,11 @@ acorn@^8.2.4: resolved "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz" integrity sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q== +acorn@^8.9.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + agent-base@6: version "6.0.2" resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" @@ -406,7 +462,7 @@ agent-base@6: dependencies: debug "4" -ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: +ajv@^6.12.3, ajv@^6.12.4: version "6.12.6" resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -416,22 +472,12 @@ ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.1: - version "8.11.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" - integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - another-json@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/another-json/-/another-json-0.2.0.tgz" integrity sha512-/Ndrl68UQLhnCdsAzEXLMFuOR546o2qbYRqCglaNHbjXrwG1ayTcdwr3zkSGOGtGXDyR5X9nCFfnyG2AFJIsqg== -ansi-colors@4.1.1, ansi-colors@^4.1.1: +ansi-colors@4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== @@ -502,11 +548,6 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== -astral-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" - integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== - async-lock@^1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/async-lock/-/async-lock-1.3.2.tgz#56668613f91c1c55432b4db73e65c9ced664e789" @@ -635,6 +676,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + braces@^3.0.1, braces@~3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" @@ -727,6 +775,11 @@ chokidar@3.5.3: optionalDependencies: fsevents "~2.3.2" +ci-info@^3.2.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" + integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== + cliui@^7.0.2: version "7.0.4" resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" @@ -899,10 +952,10 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4, debug@4.3.3, debug@^4.0.1, debug@^4.1.1: - version "4.3.3" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz" - integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== +debug@4, debug@4.3.4, debug@^4.1.1, debug@^4.3.2: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" @@ -941,10 +994,10 @@ destroy@1.2.0: resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== -diff-sequences@^27.0.6: - version "27.5.1" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" - integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== +diff-sequences@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" + integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== diff@5.0.0: version "5.0.0" @@ -1073,13 +1126,6 @@ encodeurl@~1.0.2: resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -enquirer@^2.3.5: - version "2.3.6" - resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - entities@^2.0.0: version "2.2.0" resolved "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz" @@ -1127,95 +1173,80 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" -eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== +eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== dependencies: esrecurse "^4.3.0" - estraverse "^4.1.1" + estraverse "^5.2.0" -eslint-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + +eslint@^8.49: + version "8.49.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.49.0.tgz#09d80a89bdb4edee2efcf6964623af1054bf6d42" + integrity sha512-jw03ENfm6VJI0jA9U+8H5zfl5b+FvuU3YYvZRdZHOlU2ggJkxrlkJH4HcDrZpj6YwD8kuYqvQM8LyesoazrSOQ== dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - -eslint-visitor-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz" - integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== - -eslint@^7.32: - version "7.32.0" - resolved "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz" - integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== - dependencies: - "@babel/code-frame" "7.12.11" - "@eslint/eslintrc" "^0.4.3" - "@humanwhocodes/config-array" "^0.5.0" - ajv "^6.10.0" + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.2" + "@eslint/js" "8.49.0" + "@humanwhocodes/config-array" "^0.11.11" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + ajv "^6.12.4" chalk "^4.0.0" cross-spawn "^7.0.2" - debug "^4.0.1" + debug "^4.3.2" doctrine "^3.0.0" - enquirer "^2.3.5" escape-string-regexp "^4.0.0" - eslint-scope "^5.1.1" - eslint-utils "^2.1.0" - eslint-visitor-keys "^2.0.0" - espree "^7.3.1" - esquery "^1.4.0" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.3" + espree "^9.6.1" + esquery "^1.4.2" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^5.1.2" - globals "^13.6.0" - ignore "^4.0.6" - import-fresh "^3.0.0" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" imurmurhash "^0.1.4" is-glob "^4.0.0" - js-yaml "^3.13.1" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" lodash.merge "^4.6.2" - minimatch "^3.0.4" + minimatch "^3.1.2" natural-compare "^1.4.0" - optionator "^0.9.1" - progress "^2.0.0" - regexpp "^3.1.0" - semver "^7.2.1" - strip-ansi "^6.0.0" - strip-json-comments "^3.1.0" - table "^6.0.9" + optionator "^0.9.3" + strip-ansi "^6.0.1" text-table "^0.2.0" - v8-compile-cache "^2.0.3" -espree@^7.3.0, espree@^7.3.1: - version "7.3.1" - resolved "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz" - integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== +espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== dependencies: - acorn "^7.4.0" - acorn-jsx "^5.3.1" - eslint-visitor-keys "^1.3.0" + acorn "^8.9.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esquery@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== +esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== dependencies: estraverse "^5.1.0" @@ -1226,11 +1257,6 @@ esrecurse@^4.3.0: dependencies: estraverse "^5.2.0" -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - estraverse@^5.1.0, estraverse@^5.2.0: version "5.2.0" resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz" @@ -1251,17 +1277,16 @@ eventemitter3@^4.0.4: resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== -expect@^27.0.6: - version "27.2.4" - resolved "https://registry.npmjs.org/expect/-/expect-27.2.4.tgz" - integrity sha512-gOtuonQ8TCnbNNCSw2fhVzRf8EFYDII4nB5NmG4IEV0rbUnW1I5zXvoTntU4iicB/Uh0oZr20NGlOLdJiwsOZA== +expect@^29.6.4: + version "29.6.4" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.6.4.tgz#a6e6f66d4613717859b2fe3da98a739437b6f4b8" + integrity sha512-F2W2UyQ8XYyftHT57dtfg8Ue3X5qLgm2sSug0ivvLRH/VKNRL/pDxg/TH7zVzbQB0tu80clNFy6LU7OS/VSEKA== dependencies: - "@jest/types" "^27.2.4" - ansi-styles "^5.0.0" - jest-get-type "^27.0.6" - jest-matcher-utils "^27.2.4" - jest-message-util "^27.2.4" - jest-regex-util "^27.0.6" + "@jest/expect-utils" "^29.6.4" + jest-get-type "^29.6.3" + jest-matcher-utils "^29.6.4" + jest-message-util "^29.6.3" + jest-util "^29.6.3" express-rate-limit@^6.7.0: version "6.7.0" @@ -1335,6 +1360,13 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +fastq@^1.6.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + dependencies: + reusify "^1.0.4" + fecha@^4.2.0: version "4.2.3" resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd" @@ -1374,7 +1406,7 @@ finalhandler@1.2.0: statuses "2.0.1" unpipe "~1.0.0" -find-up@5.0.0: +find-up@5.0.0, find-up@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== @@ -1476,11 +1508,6 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - generate-function@^2.0.0: version "2.3.1" resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.3.1.tgz#f069617690c10c868e73b8465746764f97c3479f" @@ -1516,7 +1543,14 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -glob-parent@^5.1.2, glob-parent@~5.1.2: +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -1528,7 +1562,7 @@ glob-to-regexp@^0.4.1: resolved "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@7.2.0, glob@^7.1.1: +glob@7.2.0: version "7.2.0" resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz" integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== @@ -1540,7 +1574,7 @@ glob@7.2.0, glob@^7.1.1: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.1.3: +glob@^7.1.1, glob@^7.1.3: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== @@ -1552,10 +1586,10 @@ glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" -globals@^13.6.0, globals@^13.9.0: - version "13.11.0" - resolved "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz" - integrity sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g== +globals@^13.19.0: + version "13.21.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.21.0.tgz#163aae12f34ef502f5153cfbdd3600f36c63c571" + integrity sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg== dependencies: type-fest "^0.20.2" @@ -1564,15 +1598,15 @@ graceful-fs@^4.1.3: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== -graceful-fs@^4.2.4: - version "4.2.8" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" - integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== +graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== har-schema@^2.0.0: version "2.0.0" @@ -1740,17 +1774,17 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== +ignore@^5.2.0: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== immediate@~3.0.5: version "3.0.6" resolved "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz" integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== -import-fresh@^3.0.0, import-fresh@^3.2.1: +import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -1826,7 +1860,7 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== @@ -1854,6 +1888,11 @@ is-number@^7.0.0: resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + is-plain-obj@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" @@ -1904,50 +1943,57 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== -jest-diff@^27.2.4: - version "27.2.4" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.2.4.tgz#171c51d3d2c105c457100fee6e7bf7cee51c8d8c" - integrity sha512-bLAVlDSCR3gqUPGv+4nzVpEXGsHh98HjUL7Vb2hVyyuBDoQmja8eJb0imUABsuxBeUVmf47taJSAd9nDrwWKEg== +jest-diff@^29.6.4: + version "29.6.4" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.6.4.tgz#85aaa6c92a79ae8cd9a54ebae8d5b6d9a513314a" + integrity sha512-9F48UxR9e4XOEZvoUXEHSWY4qC4zERJaOfrbBg9JpbJOO43R1vN76REt/aMGZoY6GD5g84nnJiBIVlscegefpw== dependencies: chalk "^4.0.0" - diff-sequences "^27.0.6" - jest-get-type "^27.0.6" - pretty-format "^27.2.4" + diff-sequences "^29.6.3" + jest-get-type "^29.6.3" + pretty-format "^29.6.3" -jest-get-type@^27.0.6: - version "27.0.6" - resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz" - integrity sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg== +jest-get-type@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" + integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== -jest-matcher-utils@^27.2.4: - version "27.2.4" - resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.2.4.tgz" - integrity sha512-nQeLfFAIPPkyhkDfifAPfP/U5wm1x0fLtAzqXZSSKckXDNuk2aaOfQiDYv1Mgf5GY6yOsxfUnvNm3dDjXM+BXw== +jest-matcher-utils@^29.6.4: + version "29.6.4" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.6.4.tgz#327db7ababea49455df3b23e5d6109fe0c709d24" + integrity sha512-KSzwyzGvK4HcfnserYqJHYi7sZVqdREJ9DMPAKVbS98JsIAvumihaNUbjrWw0St7p9IY7A9UskCW5MYlGmBQFQ== dependencies: chalk "^4.0.0" - jest-diff "^27.2.4" - jest-get-type "^27.0.6" - pretty-format "^27.2.4" + jest-diff "^29.6.4" + jest-get-type "^29.6.3" + pretty-format "^29.6.3" -jest-message-util@^27.2.4: - version "27.2.4" - resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.2.4.tgz" - integrity sha512-wbKT/BNGnBVB9nzi+IoaLkXt6fbSvqUxx+IYY66YFh96J3goY33BAaNG3uPqaw/Sh/FR9YpXGVDfd5DJdbh4nA== +jest-message-util@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.6.3.tgz#bce16050d86801b165f20cfde34dc01d3cf85fbf" + integrity sha512-FtzaEEHzjDpQp51HX4UMkPZjy46ati4T5pEMyM6Ik48ztu4T9LQplZ6OsimHx7EuM9dfEh5HJa6D3trEftu3dA== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^27.2.4" + "@jest/types" "^29.6.3" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" - graceful-fs "^4.2.4" + graceful-fs "^4.2.9" micromatch "^4.0.4" - pretty-format "^27.2.4" + pretty-format "^29.6.3" slash "^3.0.0" stack-utils "^2.0.3" -jest-regex-util@^27.0.6: - version "27.0.6" - resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz" - integrity sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ== +jest-util@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.6.3.tgz#e15c3eac8716440d1ed076f09bc63ace1aebca63" + integrity sha512-QUjna/xSy4B32fzcKTSz1w7YYzgiHrjjJjevdRf61HYk998R5vVMMNmrHESYZVDS5DSWs+1srPLPKxXPkeSDOA== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" js-tokens@^4.0.0: version "4.0.0" @@ -2017,11 +2063,6 @@ json-schema-traverse@^0.4.1: resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - json-schema@0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" @@ -2111,21 +2152,11 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" -lodash.clonedeep@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== - lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash.truncate@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" - integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== - lodash@4, lodash@^4.17.19, lodash@^4.7.0: version "4.17.21" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" @@ -2169,13 +2200,6 @@ lru-cache@^4.1.5: pseudomap "^1.0.2" yallist "^2.1.2" -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - lru-cache@^7.10.1: version "7.13.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.13.1.tgz#267a81fbd0881327c46a81c5922606a2cfe336c4" @@ -2295,14 +2319,14 @@ minimalistic-assert@^1.0.1: resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimatch@4.2.1: - version "4.2.1" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz" - integrity sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g== +minimatch@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== dependencies: - brace-expansion "^1.1.7" + brace-expansion "^2.0.1" -minimatch@^3.0.4, minimatch@^3.1.1: +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -2333,32 +2357,29 @@ mkdirp@~0.5.1: dependencies: minimist "^1.2.6" -mocha@^9.0.1: - version "9.2.2" - resolved "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz" - integrity sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g== +mocha@^10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" + integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== dependencies: - "@ungap/promise-all-settled" "1.1.2" ansi-colors "4.1.1" browser-stdout "1.3.1" chokidar "3.5.3" - debug "4.3.3" + debug "4.3.4" diff "5.0.0" escape-string-regexp "4.0.0" find-up "5.0.0" glob "7.2.0" - growl "1.10.5" he "1.2.0" js-yaml "4.1.0" log-symbols "4.1.0" - minimatch "4.2.1" + minimatch "5.0.1" ms "2.1.3" - nanoid "3.3.1" + nanoid "3.3.3" serialize-javascript "6.0.0" strip-json-comments "3.1.1" supports-color "8.1.1" - which "2.0.2" - workerpool "6.2.0" + workerpool "6.2.1" yargs "16.2.0" yargs-parser "20.2.4" yargs-unparser "2.0.0" @@ -2399,10 +2420,10 @@ ms@2.1.3, ms@^2.1.1: resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -nanoid@3.3.1: - version "3.3.1" - resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz" - integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== +nanoid@3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== nanoid@^3.3.4: version "3.3.4" @@ -2522,17 +2543,17 @@ optionator@^0.8.1: type-check "~0.3.2" word-wrap "~1.2.3" -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== +optionator@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" deep-is "^0.1.3" fast-levenshtein "^2.0.6" levn "^0.4.1" prelude-ls "^1.2.1" type-check "^0.4.0" - word-wrap "^1.2.3" p-finally@^1.0.0: version "1.0.0" @@ -2755,20 +2776,14 @@ prelude-ls@~1.1.2: resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz" integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== -pretty-format@^27.2.4: - version "27.2.4" - resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-27.2.4.tgz" - integrity sha512-NUjw22WJHldzxyps2YjLZkUj6q1HvjqFezkB9Y2cklN8NtVZN/kZEXGZdFw4uny3oENzV5EEMESrkI0YDUH8vg== +pretty-format@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.6.3.tgz#d432bb4f1ca6f9463410c3fb25a0ba88e594ace7" + integrity sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw== dependencies: - "@jest/types" "^27.2.4" - ansi-regex "^5.0.1" + "@jest/schemas" "^29.6.3" ansi-styles "^5.0.0" - react-is "^17.0.1" - -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + react-is "^18.0.0" prom-client@^14.1.0: version "14.1.0" @@ -2824,6 +2839,11 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + railroad-diagrams@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz" @@ -2859,10 +2879,10 @@ raw-body@2.5.1: iconv-lite "0.4.24" unpipe "1.0.0" -react-is@^17.0.1: - version "17.0.2" - resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz" - integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== +react-is@^18.0.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== readable-stream@^3.4.0, readable-stream@^3.6.0: version "3.6.0" @@ -2880,11 +2900,6 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" -regexpp@^3.1.0: - version "3.2.0" - resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz" - integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== - request-promise-core@1.1.4: version "1.1.4" resolved "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz" @@ -2933,11 +2948,6 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" @@ -2956,6 +2966,11 @@ ret@~0.1.10: resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -2963,6 +2978,13 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + safe-buffer@5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" @@ -3014,13 +3036,6 @@ semver@^5.3.0, semver@^5.6.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^7.2.1: - version "7.5.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" - send@0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" @@ -3105,15 +3120,6 @@ slash@^3.0.0: resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -slice-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" - integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz" @@ -3219,7 +3225,7 @@ strip-bom@^3.0.0: resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== -strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: +strip-json-comments@3.1.1, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== @@ -3250,18 +3256,6 @@ symbol-tree@^3.2.4: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== -table@^6.0.9: - version "6.7.1" - resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2" - integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg== - dependencies: - ajv "^8.0.1" - lodash.clonedeep "^4.5.0" - lodash.truncate "^4.4.2" - slice-ansi "^4.0.0" - string-width "^4.2.0" - strip-ansi "^6.0.0" - tdigest@^0.1.1: version "0.1.2" resolved "https://registry.npmjs.org/tdigest/-/tdigest-0.1.2.tgz" @@ -3320,10 +3314,10 @@ triple-beam@^1.3.0: resolved "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz" integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== -ts-mocha@^9.0.2: - version "9.0.2" - resolved "https://registry.npmjs.org/ts-mocha/-/ts-mocha-9.0.2.tgz" - integrity sha512-WyQjvnzwrrubl0JT7EC1yWmNpcsU3fOuBFfdps30zbmFBgKniSaSOyZMZx+Wq7kytUs5CY+pEbSYEbGfIKnXTw== +ts-mocha@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/ts-mocha/-/ts-mocha-10.0.0.tgz#41a8d099ac90dbbc64b06976c5025ffaebc53cb9" + integrity sha512-VRfgDO+iiuJFlNB18tzOfypJ21xn2xbuZyDvJvqpTbWgkAgD17ONGr8t+Tl8rcBtOBdjXp5e/Rk+d39f7XBHRw== dependencies: ts-node "7.0.1" optionalDependencies: @@ -3431,10 +3425,10 @@ typescript-formatter@^7.2: commandpost "^1.0.0" editorconfig "^0.15.0" -typescript@^5.1.6: - version "5.1.6" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" - integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== +typescript@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" + integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== ulidx@^0.3.0: version "0.3.0" @@ -3485,11 +3479,6 @@ uuid@^8.3.2: resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== -v8-compile-cache@^2.0.3: - version "2.3.0" - resolved "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - vary@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" @@ -3549,7 +3538,7 @@ whatwg-url@^8.0.0, whatwg-url@^8.5.0: tr46 "^2.1.0" webidl-conversions "^6.1.0" -which@2.0.2, which@^2.0.1: +which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== @@ -3591,15 +3580,15 @@ winston@^3.3.3: triple-beam "^1.3.0" winston-transport "^4.5.0" -word-wrap@^1.2.3, word-wrap@~1.2.3: +word-wrap@~1.2.3: version "1.2.4" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.4.tgz#cb4b50ec9aca570abd1f52f33cd45b6c61739a9f" integrity sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA== -workerpool@6.2.0: - version "6.2.0" - resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz" - integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== +workerpool@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" + integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== wrap-ansi@^7.0.0: version "7.0.0" @@ -3645,11 +3634,6 @@ yallist@^2.1.2: resolved "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz" integrity sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A== -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - yaml@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.2.2.tgz#ec551ef37326e6d42872dad1970300f8eb83a073" From 2330ddc71977c79dfe3f1e3b2174711a10277bb3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 14:44:16 +0100 Subject: [PATCH 18/23] Bump the everything group with 4 updates (#115) Bumps the everything group with 4 updates: [actions/checkout](https://github.com/actions/checkout), [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action), [docker/login-action](https://github.com/docker/login-action) and [baptiste0928/cargo-install](https://github.com/baptiste0928/cargo-install). Updates `actions/checkout` from 2 to 4 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v4) Updates `docker/setup-buildx-action` from 2.6.0 to 2.10.0 - [Release notes](https://github.com/docker/setup-buildx-action/releases) - [Commits](https://github.com/docker/setup-buildx-action/compare/v2.6.0...v2.10.0) Updates `docker/login-action` from 1 to 2 - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/v1...v2) Updates `baptiste0928/cargo-install` from 1 to 2 - [Release notes](https://github.com/baptiste0928/cargo-install/releases) - [Changelog](https://github.com/baptiste0928/cargo-install/blob/main/CHANGELOG.md) - [Commits](https://github.com/baptiste0928/cargo-install/compare/v1...v2) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major dependency-group: everything - dependency-name: docker/setup-buildx-action dependency-type: direct:production update-type: version-update:semver-minor dependency-group: everything - dependency-name: docker/login-action dependency-type: direct:production update-type: version-update:semver-major dependency-group: everything - dependency-name: baptiste0928/cargo-install dependency-type: direct:production update-type: version-update:semver-major dependency-group: everything ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docker-hub-develop.yml | 6 +++--- .github/workflows/docker-hub-release.yml | 6 +++--- .github/workflows/mjolnir.yml | 12 ++++++------ 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/docker-hub-develop.yml b/.github/workflows/docker-hub-develop.yml index c38fa992..d6b1edf3 100644 --- a/.github/workflows/docker-hub-develop.yml +++ b/.github/workflows/docker-hub-develop.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Unshallow for git describe so we can create version.txt run: git fetch --prune --unshallow --tags --all --force - name: Prepare version file @@ -29,10 +29,10 @@ jobs: uses: docker/setup-qemu-action@v2.2.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2.6.0 + uses: docker/setup-buildx-action@v2.10.0 - name: Log in to Docker Hub - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/.github/workflows/docker-hub-release.yml b/.github/workflows/docker-hub-release.yml index d6aecc13..b23d1796 100644 --- a/.github/workflows/docker-hub-release.yml +++ b/.github/workflows/docker-hub-release.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Get release tag run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV - name: Unshallow for git describe so we can create version.txt @@ -28,10 +28,10 @@ jobs: uses: docker/setup-qemu-action@v2.2.0 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2.6.0 + uses: docker/setup-buildx-action@v2.10.0 - name: Log in to Docker Hub - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/.github/workflows/mjolnir.yml b/.github/workflows/mjolnir.yml index 094a5891..7bd3db32 100644 --- a/.github/workflows/mjolnir.yml +++ b/.github/workflows/mjolnir.yml @@ -15,7 +15,7 @@ jobs: name: Build & Lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Specifically use node 18 like in the readme. uses: actions/setup-node@v3 @@ -28,7 +28,7 @@ jobs: name: Unit tests runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Specifically use node 18 like in the readme. uses: actions/setup-node@v3 with: @@ -40,12 +40,12 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 60 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-node@v3 with: node-version: '18' - name: Fetch and build mx-tester (cached across runs) - uses: baptiste0928/cargo-install@v1 + uses: baptiste0928/cargo-install@v2 with: crate: mx-tester version: "0.3.3" @@ -62,12 +62,12 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 30 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-node@v3 with: node-version: '18' - name: Fetch and build mx-tester (cached across runs) - uses: baptiste0928/cargo-install@v1 + uses: baptiste0928/cargo-install@v2 with: crate: mx-tester version: "0.3.3" From a328f525583c4e66caf2dfa93198512fe5758f76 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 15:03:58 +0100 Subject: [PATCH 19/23] Bump yaml from 2.2.2 to 2.3.2 (#111) Bumps [yaml](https://github.com/eemeli/yaml) from 2.2.2 to 2.3.2. - [Release notes](https://github.com/eemeli/yaml/releases) - [Commits](https://github.com/eemeli/yaml/compare/v2.2.2...v2.3.2) --- updated-dependencies: - dependency-name: yaml dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 637d75f5..14cda73b 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "pg": "^8.8.0", "shell-quote": "^1.7.3", "ulidx": "^0.3.0", - "yaml": "^2.2.2" + "yaml": "^2.3.2" }, "engines": { "node": ">=18.0.0" diff --git a/yarn.lock b/yarn.lock index 344ffc26..0ad71942 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3634,10 +3634,10 @@ yallist@^2.1.2: resolved "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz" integrity sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A== -yaml@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.2.2.tgz#ec551ef37326e6d42872dad1970300f8eb83a073" - integrity sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA== +yaml@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.2.tgz#f522db4313c671a0ca963a75670f1c12ea909144" + integrity sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg== yargs-parser@20.2.4: version "20.2.4" From 6694bf547e64a8d359a4f52931788e71b7794690 Mon Sep 17 00:00:00 2001 From: Aminda Suomalainen Date: Mon, 11 Sep 2023 17:04:28 +0300 Subject: [PATCH 20/23] dependabot.yml: rename everything to github-actions (#120) I didn't know the "everything" would be visible in PR title like that and it bothers me as it's not really "everything", it's just github-actions. --- .github/dependabot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 43f8fdac..d3c6e9c8 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -13,6 +13,6 @@ updates: schedule: interval: "daily" groups: - everything: + github-actions: patterns: - "*" From 272d81946b946aeae3b8eac9fe38f1c655334f25 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 15:08:49 +0100 Subject: [PATCH 21/23] Bump config and @types/config (#118) Bumps [config](https://github.com/node-config/node-config) and [@types/config](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/config). These dependencies needed to be updated together. Updates `config` from 3.3.8 to 3.3.9 - [Release notes](https://github.com/node-config/node-config/releases) - [Changelog](https://github.com/node-config/node-config/blob/master/History.md) - [Commits](https://github.com/node-config/node-config/compare/v3.3.8...v3.3.9) Updates `@types/config` from 3.3.0 to 3.3.1 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/config) --- updated-dependencies: - dependency-name: config dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: "@types/config" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 4 ++-- yarn.lock | 26 +++++++++++++------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 14cda73b..277c4c16 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "version": "sed -i '/# version automated/s/[0-9][0-9]*\\.[0-9][0-9]*\\.[0-9][^\"]*/'$npm_package_version'/' synapse_antispam/setup.py && git add synapse_antispam/setup.py && cat synapse_antispam/setup.py" }, "devDependencies": { - "@types/config": "^3.3.0", + "@types/config": "^3.3.1", "@types/crypto-js": "^4.1.2", "@types/express": "^4.17.13", "@types/html-to-text": "^8.0.1", @@ -50,7 +50,7 @@ "@sentry/tracing": "^7.17.2", "await-lock": "^2.2.2", "body-parser": "^1.20.1", - "config": "^3.3.8", + "config": "^3.3.9", "express": "^4.17", "html-to-text": "^8.0.0", "humanize-duration": "^3.27.1", diff --git a/yarn.lock b/yarn.lock index 0ad71942..9b53eee2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -229,10 +229,10 @@ resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.2.tgz#f65d3d6389e01eeb458bd54dc8f52b95a9463bc8" integrity sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w== -"@types/config@^3.3.0": - version "3.3.0" - resolved "https://registry.yarnpkg.com/@types/config/-/config-3.3.0.tgz#2b632cb37c639bf8d57054561f5a77d31dcebc1e" - integrity sha512-9kZSbl3/X3TVNowLCu5HFQdQmD+4287Om55avknEYkuo6R2dDrsp/EXEHUFvfYeG7m1eJ0WYGj+cbcUIhARJAQ== +"@types/config@^3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@types/config/-/config-3.3.1.tgz#eb385f254cd08381db4dda7b9bef4cc2fd400e5d" + integrity sha512-ZhBk8IVIbc3cuES10j2I+xa3L68rpl1X35FdsNce/AiE7yJnhQaA7tvO5MRZblqpBny4OIddJ+WQL04I1933Zg== "@types/connect@*": version "3.4.35" @@ -859,12 +859,12 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -config@^3.3.8: - version "3.3.8" - resolved "https://registry.yarnpkg.com/config/-/config-3.3.8.tgz#14ef7aef22af25877fdaee696ec64d761feb7be0" - integrity sha512-rFzF6VESOdp7wAXFlB9IOZI4ouL05g3A03v2eRcTHj2JBQaTNJ40zhAUl5wRbWHqLZ+uqp/7OE0BWWtAVgrong== +config@^3.3.9: + version "3.3.9" + resolved "https://registry.yarnpkg.com/config/-/config-3.3.9.tgz#27fae95b43e0e1d5723e54143c090954d8e49572" + integrity sha512-G17nfe+cY7kR0wVpc49NCYvNtelm/pPy8czHoFkAgtV1lkmcp7DHtWCdDu+C9Z7gb2WVqa9Tm3uF9aKaPbCfhg== dependencies: - json5 "^2.2.1" + json5 "^2.2.3" content-disposition@0.5.4: version "0.5.4" @@ -2085,10 +2085,10 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" -json5@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" - integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== +json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== jsonpointer@^5.0.0: version "5.0.1" From 69b72097394829cd12421bf05d60eb20df33ab8a Mon Sep 17 00:00:00 2001 From: Gnuxie <50846879+Gnuxie@users.noreply.github.com> Date: Tue, 12 Sep 2023 11:57:50 +0100 Subject: [PATCH 22/23] Fix RoomUpdateError roomId argument typo (#123) We were clearly in the process of deleting the member decleration to just have the decleration be in the constructor. When we were distracted, leaving a property named `readonly`, which shouldn't be possible imo, need to add some rule for that prompto. --- src/ProtectedRoomsSet.ts | 2 +- src/models/RoomUpdateError.tsx | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/ProtectedRoomsSet.ts b/src/ProtectedRoomsSet.ts index 0bddbd3e..d0b00943 100644 --- a/src/ProtectedRoomsSet.ts +++ b/src/ProtectedRoomsSet.ts @@ -466,7 +466,7 @@ export class ProtectedRoomsSet { errors: IRoomUpdateError[], renderOptions: { title?: string, noErrorsText?: string } ): Promise { - printActionResult(this.client, this.managementRoomId, errors, renderOptions); + await printActionResult(this.client, this.managementRoomId, errors, renderOptions); } public async unbanUser(user: string): Promise { diff --git a/src/models/RoomUpdateError.tsx b/src/models/RoomUpdateError.tsx index c98e2ba7..e760d281 100644 --- a/src/models/RoomUpdateError.tsx +++ b/src/models/RoomUpdateError.tsx @@ -48,9 +48,7 @@ export class PermissionError extends CommandError implements IRoomUpdateError { } export class RoomUpdateException extends CommandException implements IRoomUpdateError { - roomId: string; - - constructor(public readonly: string, ...args: ConstructorParameters) { + constructor(public readonly roomId: string, ...args: ConstructorParameters) { super(...args); } From efe842cc9f6fc67185702169933ecf7408bcb2e8 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Tue, 12 Sep 2023 11:58:14 +0100 Subject: [PATCH 23/23] v1.85.1 --- package.json | 2 +- synapse_antispam/setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 277c4c16..6b9b122f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "draupnir", - "version": "1.85.0", + "version": "1.85.1", "description": "A moderation tool for Matrix", "main": "lib/index.js", "repository": "https://github.com/Gnuxie/Draupnir.git", diff --git a/synapse_antispam/setup.py b/synapse_antispam/setup.py index 20d00d5a..1aed3c95 100644 --- a/synapse_antispam/setup.py +++ b/synapse_antispam/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name="mjolnir", - version="1.85.0", # version automated in package.json - Do not edit this line, use `yarn version`. + version="1.85.1", # version automated in package.json - Do not edit this line, use `yarn version`. packages=find_packages(), description="Mjolnir Antispam", include_package_data=True,